提问人:adhocEY 提问时间:8/17/2023 最后编辑:adhocEY 更新时间:8/19/2023 访问量:54
在 SSRS 中,如何根据日期参数显示过去的销售汇总结果?
In SSRS, How to display past sales summarized results based on date parameter?
问:
我正在构建一个 SSRS 报表,显示已售商品的基本销售历史记录。用户输入项目 #、开始日期和结束日期作为参数。主表逐行显示输入物料的销售信息以及开始/结束日期之间的销售日期。
作为报告的一部分,我想在文本框中包含一些关键的汇总数据,这些数据将显示:
- 过去 6 个月售出数量
- 今年售出数量
- 去年售出数量
如果我能将它们标记为“2022 年售出的数量”(去年),并根据输入的“开始日期”参数进行更新,那就更好了。因此,如果用户输入的开始日期是 2021 年的某个时间,它将显示为“2020 年售出的数量”。
我正在努力知道如何汇总数量并根据开始日期和结束日期更改正在查看的日期范围。
示例数据:
参数:开始日期=2023年1月1日 结束日期=2023年2月28日 商品编号=009833
刊登日期 | 订货号 | 客户 | 商品编号 | 数量。 |
---|---|---|---|---|
一月/01/2023 | 25467 | 乔·史密斯 | 009833 | 4 |
2月/06/2023 | 26802 | 彼得 | 009833 | 27 |
2月 20/2023 | 26980 | 桑德拉· | 009833 | 11 |
已编辑以添加代码 8/18/2023:
WITH
----This CTE Gathers Sales Invoice / Cr. Memo Header data from 4 different sources----
CTE_SalesHeaderData (DocN, NoSeries, OrderNo, PostingDate, Cust_Name)
AS
(SELECT SIH.[No_], SIH.[No_ Series], SIH.[Order No_], SIH.[Posting Date], SIH.[Sell-to Customer Name]
FROM [Sales Invoice Header] SIH
UNION ALL
SELECT SCRMH.[No_], SCRMH.[No_ Series], SCRMH.[Order No_], SCRMH.[Posting Date], SCRMH.[Sell-to Customer Name]
FROM [Sales Cr_Memo Header] SCRMH
UNION ALL
SELECT SVIH.[No_], SVIH.[No_ Series], SVIH.[Order No_], SVIH.[Posting Date], SVIH.[Bill-to Name]
FROM [Service Invoice Header] SVIH
UNION ALL
SELECT SVCRMH.[No_], SVCRMH.[No_ Series], SVCRMH.[Order No_], SVCRMH.[Posting Date], SVCRMH.[Bill-to Name]
FROM [Service Cr_Memo Header] SVCRMH),
----This CTE Gathers Sales Invoice / Cr. Memo Line data for the 4 sources (relates to the 4 sources in 1st CTE) ----
CTE_SalesLinesData (DocNo2,ItemNo,Qty)
AS
(SELECT SIL.[Document No_], SIL.[No_], SIL.[Quantity]
FROM [Sales Invoice Line] SIL
WHERE SIL.[Type] <> '1'
GROUP BY SIL.[Document No_], SIL.[No_], SIL.[Quantity]
UNION ALL
SELECT SCRML.[Document No_], SCRML.[No_], SCRML.[Quantity]
FROM [Sales Cr_Memo Line] SCRML
WHERE SCRML.[Type] <> '1'
GROUP BY SCRML.[Document No_], SCRML.[No_], SCRML.[Quantity]
UNION ALL
SELECT SVIL.[Document No_], SVIL.[No_], SVIL.[Quantity]
FROM [Service Invoice Line] SVIL
WHERE SVIL.[Type] = '1' OR SVIL.[Type] = '2'
GROUP BY SVIL.[Document No_], SVIL.[No_], SVIL.[Quantity]
UNION ALL
SELECT SVCRML.[Document No_], SVCRML.[No_], SVCRML.[Quantity]
FROM [Service Cr_Memo Line] SVCRML
WHERE SVCRML.[Type] = '1' OR SVCRML.[Type] = '2'
GROUP BY SVCRML.[Document No_], SVCRML.[No_], SVCRML.[Quantity])
SELECT
SHD.[PostingDate],
SHD.[OrderNo],
SHD.[Cust_No],
SHD.[Cust_Name],
SLD.[ItemNo],
---- The qty. has to be manipulated as it needs to be negative if it was a Cr. Memo ----
CASE
WHEN SHD.[NoSeries] = 'SI' THEN SLD.[Qty]
WHEN SHD.[NoSeries] = 'PSI' THEN SLD.[Qty]
WHEN SHD.[NoSeries] = 'SC' THEN SLD.[Qty] * (-1)
WHEN SHD.[NoSeries] = 'PSC' THEN SLD.[Qty] * (-1)
END AS [Qty.]
---- The 1st CTE is joined to the 2nd CTE ----
FROM CTE_SalesHeaderData SHD
LEFT JOIN CTE_SalesLinesData SLD ON SLD.DocNo2 = SHD.[DocN]
GROUP BY
SHD.[PostingDate],
SHD.[DocN],
SHD.[NoSeries],
SHD.[OrderNo],
SHD.[Cust_No],
SHD.[Cust_Name],
SLD.[ItemNo],
SLD.[Qty]
HAVING
SLD.[Qty] > 0
AND (SHD.[PostingDate] BETWEEN @StartDate AND @EndDate)
AND (SLD.[ItemNo] = @ItemNo)
ORDER BY
SHD.[PostingDate]
如果需要更多信息或任何其他问题,请告诉我。谢谢。
答:
你没有提供你自己的DDL/DML(这确实有助于回答这类问题),所以我使用了我自己的随机数据,这是一个非常简单的销售类型设置。
DECLARE @StartDate DATETIME = '2023-01-01', @EndDate DATETIME = '2023-02-28 23:59:59.997', @ProductID INT = 5;
;WITH ProductHistory AS (
SELECT ii.ProductID, SUM(CASE WHEN InvoiceDateTimeUTC > DATEADD(MONTH,-6,@StartDate) THEN ii.Quantity END) AS LastSixMonths,
SUM(CASE WHEN InvoiceDateTimeUTC BETWEEN DATEFROMPARTS(DATEPART(YEAR,@StartDate)-1,1,1) AND DATEFROMPARTS(DATEPART(YEAR,@StartDate),1,1) THEN ii.Quantity END) AS PreviousCalendarYear
FROM InvoiceItems ii
INNER JOIN Invoices i
ON ii.InvoiceID = i.InvoiceID
WHERE ii.ProductID = @ProductID
AND i.InvoiceDateTimeUTC >= DATEFROMPARTS(DATEPART(YEAR,@StartDate)-1,1,1)
GROUP BY ProductID
)
SELECT i.InvoiceDateTimeUTC, i.InvoiceID, c.FirstName, c.LastName, ii.ProductID, SUM(ii.Quantity) AS TotalQuantity, ph.LastSixMonths, ph.PreviousCalendarYear, DATEPART(YEAR,@StartDate)-1 AS PreviousYearNumber
FROM InvoiceItems ii
LEFT OUTER JOIN ProductHistory ph
ON ii.ProductID = ph.ProductID
INNER JOIN Invoices i
ON ii.InvoiceID = i.InvoiceID
INNER JOIN Customers c
ON i.CustomerID = c.CustomerID
WHERE ii.ProductID = @ProductID
AND InvoiceDateTimeUTC BETWEEN @StartDate AND @EndDate
GROUP BY i.InvoiceDateTimeUTC, i.InvoiceID, c.FirstName, c.LastName, ii.ProductID, ph.LastSixMonths, ph.PreviousCalendarYear;
我们使用 here 通过操作输入参数来执行您想要的聚合,然后只需加入该参数即可。恢复动态列名称并非易事,但您可以将 PreviousYearNumber 列添加到标题中。CTE
CTE
发票日期时间UTC | 发票 ID | 名字 | 姓氏 | 产品 ID | 总数量 | 上半年 | 上一页日历年 | 上一页YearNumber |
---|---|---|---|---|---|---|---|---|
2023-01-11 14:55:15.9633333 | 357 | 乔治 | 坎贝尔 | 5 | 1 | 9030 | 8135 | 2022 |
2023-02-03 15:41:15.9633333 | 951 | 多 萝 西 | 里维拉 | 5 | 1 | 9030 | 8135 | 2022 |
2023-02-24 16:23:15.9633333 | 1722 | 黛布拉 | 门多萨 | 5 | 1 | 9030 | 8135 | 2022 |
2023-01-23 15:19:15.9633333 | 3080 | 夏佳理 | 戈麦斯 | 5 | 1 | 9030 | 8135 | 2022 |
2023-01-05 14:43:15.9633333 | 4455 | 瑞 秋 | 休斯 | 5 | 1 | 9030 | 8135 | 2022 |
2023-02-27 16:28:15.9633333 | 5898 | 黛博拉 | 罗伯茨 | 5 | 1 | 9030 | 8135 | 2022 |
2023-02-16 16:06:15.9633333 | 6070 | 夏佳理 | 戈麦斯 | 5 | 1 | 9030 | 8135 | 2022 |
2023-01-27 15:26:15.9633333 | 7163 | 威廉 | 埃尔南德斯 | 5 | 1 | 9030 | 8135 | 2022 |
2023-02-12 15:59:15.9633333 | 7482 | 雪 莉 | 奥尔蒂斯 | 5 | 1 | 9030 | 8135 | 2022 |
2023-01-17 15:07:15.9633333 | 7959 | 莱恩 | 柯林斯 | 5 | 1 | 9030 | 8135 | 2022 |
评论
DECLARE @TableName (ColumnOne INT, ColumnTwo VARCHAR(20)...); INSERT INTO @TableName (ColumnOne, ColumnTwo...) VALUES (1, 'One'...),(2, 'Two'...) ...;
Invoices
InvoiceItems
ProductID
这是一个非常通用的示例,说明我将如何处理这个问题。
据我所知,您目前有一个工作报告,它显示了两个日期之间的销售数据。因此,我假设您的数据集查询看起来是这样的
SELECT *
FROM mySalesTable
WHERE ItemNo = @ItemNo
AND PostingDate Between @StartDate AND @EndDate
现在,您想要添加一些其他摘要信息,但数据不会在主数据集中捕获,因为主数据集仅在两个特定点之间提供数据。
因此,我将创建另一个数据集,例如,并为此编写一个新查询。类似的东西..dsSummary
declare @Last6Months INT
declare @LastYear INT
declare @ThisYear INT
-- get last 6 monmths from startdate
SELECT @Last6Months = SUM(qty)
FROM mySalesTable
WHERE ItemNo = @ItemNo
AND PostingDate BETWEEN DATEADD(m, -6, @StartDate) AND @StartDate
-- get last year
SELECT @LastYear = SUM(qty)
FROM mySalesTable
WHERE ItemNo = @ItemNo
AND YEAR(PostingDate) = YEAR(@StartDate)-1
-- get this year
SELECT @ThisYear = SUM(qty)
FROM mySalesTable
WHERE ItemNo = @ItemNo
AND YEAR(PostingDate) = YEAR(@StartDate)
SELECT
@Last6Months as Last6Months,
@LastYear as LastYear,
@ThisYear as ThisYear
这仅使用您已有的参数,并基于该参数运行 3 个查询,并返回包含三个结果的单行。@StartDate
你可以用不同的方式写这个,因为它不是很有效,但我保持简单,所以很容易理解。
现在,你有了新的数据集,可以向报表添加文本框,并将表达式设置为 例如。=FIRST(Fields!Last6Month.Value, "dsSummary")
评论
ShowSummary
ShowSummary