我使用以下SQL语句按月销售的数量总结我的销售历史数据。
WITH StockSales AS
(
SELECT
CASE
WHEN Month(PostST.TxDate) = 1 THEN 'Jan'
WHEN Month(PostST.TxDate) = 2 THEN 'Feb'
WHEN Month(PostST.TxDate) = 3 THEN 'Mar'
WHEN Month(PostST.TxDate) = 4 THEN 'Apr'
WHEN Month(PostST.TxDate) = 5 THEN 'May'
WHEN Month(PostST.TxDate) = 6 THEN 'Jun'
WHEN Month(PostST.TxDate) = 7 THEN 'Jul'
WHEN Month(PostST.TxDate) = 8 THEN 'Aug'
WHEN Month(PostST.TxDate) = 9 THEN 'Sept'
WHEN Month(PostST.TxDate) = 10 THEN 'Oct'
WHEN Month(PostST.TxDate) = 11 THEN 'Nov'
WHEN Month(PostST.TxDate) = 12 THEN 'Dec'
END AS MonthSold,
YEAR(PostST.TxDate) AS YearSold,
CONCAT(StkItem.Description_1, ' - ', StkItem.Code) AS Item,
CASE
WHEN PostST.TrCodeID = 30 THEN PostST.Quantity * -1
WHEN PostST.TrCodeID = 34 THEN PostST.Quantity * 1
ELSE 0
END AS QtySold
FROM
StkItem
INNER JOIN
PostST ON PostST.AccountLink = StkItem.StockLink
WHERE
PostST.TrCodeID IN (34, 30)
)
SELECT
StockSales.MonthSold,
StockSales.YearSold,
StockSales.Item,
SUM (StockSales.QtySold) AS QtySold
FROM
StockSales
GROUP BY
StockSales.QtySold, StockSales.MonthSold, StockSales.YearSold, StockSales.Item
我得到以下格式:
但是,我想要的是项目只出现一次(分组),然后每个月和每年作为一个单独的字段,每个月都有一个QtySold的SUM。
作为一个例子,我刚刚在Excel中设置了我想要的样子:
有没有办法以不同方式设置字段?
谢谢:)
答案 0 :(得分:0)
您需要“旋转”数据以获得所需格式的结果。
<强> Excel中强>
一种方法是将数据导入Excel,您可以在其中根据数据创建数据透视表,以构建所需的结构。快速的方法是:
创建数据透视表后,您可以选择行轴上的项目,列上的年份和月份以及#sold as values。
<强> SSRS 强>
如果您有可用的SQL Server Reporting服务,还可以通过SSRS报告中的Tablix来旋转表。
SQL Server 另一个选项是PIVOT SQL命令,请参见此处https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx。
这不是我经常做的事情,因为当您在编写查询时知道所需的精确列标题(旋转字段)时,它才真正有用,因为您仍需要指定所有列中的查询。
例如,如果你有一个像静态货币组这样的固定数据集,那么效果很好。
如果您有动态数据(例如您的情况下,可能会更改一组年/月),那么它不是那么有用,但如果您有固定的报告期,则可能没问题。
答案 1 :(得分:0)
首先,您需要以所需格式转换月份,您可以通过在cte中使用belwo脚本来实现:
SELECT
CASE
WHEN Month(PostST.TxDate) = 1 THEN 'Jan'
WHEN Month(PostST.TxDate) = 2 THEN 'Feb'
.
.
.
WHEN Month(PostST.TxDate) = 12 THEN 'Dec'
END) + CAST ( YEAR(PostST.TxDate) AS VARCHAR) AS MonthSold,
.
然后使用SQL pivot来转动数据:
SELECT * FROM ( SELECT MonthSold, YearSold, Item, QtySold
FROM
StockSales ) as data1
PIVOT ( SUM( QtySold ) FOR MonthSold IN ( 'Jan-13', 'Feb-13', 'Mar-13', 'Jan-14', 'Feb-14', 'Jan-15') ) AS PivotData
您必须手动将所有monthSold值放入FOR MonthSold IN()值。还有另一种方法,动态sql,可以让你自动处理它。您可以尝试此脚本,并查找该方法。希望它有所帮助
答案 2 :(得分:-1)
使用带有数据透视表的CTE
WITH Sales_CTE (Employee_No, [Employee Name], MonthSold,Amount)
AS
-- Define the CTE query.
(
SELECT EMP.Employee_No,Emp.First_Name+' '+Emp.Last_Name [Employee Name],
CASE
WHEN Month(SLC.Post_Date) = 1 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Jan'
WHEN Month(SLC.Post_Date) = 2 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Feb'
WHEN Month(SLC.Post_Date) = 3 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Mar'
WHEN Month(SLC.Post_Date) = 4 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Apr'
WHEN Month(SLC.Post_Date) = 5 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-May'
WHEN Month(SLC.Post_Date) = 6 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Jun'
WHEN Month(SLC.Post_Date) = 7 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Jul'
WHEN Month(SLC.Post_Date) = 8 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Aug'
WHEN Month(SLC.Post_Date) = 9 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Sep'
WHEN Month(SLC.Post_Date) = 10 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Oct'
WHEN Month(SLC.Post_Date) = 11 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Nov'
WHEN Month(SLC.Post_Date) = 12 THEN CAST (right(YEAR(SLC.Post_Date),2) AS VARCHAR)+'-Dec'
END AS [MonthSold],
CASE WHEN SLC.Transaction_Type IN ('B')
THEN SLC.Commission_Received_Amount ELSE SLC.Commission_Amount + IsNULL(SLC.Pleasant_ChargeBack_Amount, 0)
+ IsNULL(SLC.Preferred_ChargeBack_Amount, 0) + IsNULL(SLC.Non_Preferred_ChargeBack_Amount, 0) + IsNULL(SLC.Other_ChargeBack_Amount, 0)
END AS [Amount]
FROM tbl_Sales SLC JOIN
tbl_Employee EMP ON (EMP.Employee_ID = SLC.Employee_ID AND EMP.Load_Status = '0' AND SLC.Invoice_Status <> 'V') LEFT OUTER JOIN
tbl_Preferred PRV ON (PRV.Segment_Type = SLC.Segment_Type AND PRV.Club_Code = SLC.Club_Code AND PRV.Vendor_Code = SLC.Vendor_Code AND
PRV.Effective_Date <= SLC.Post_Date AND PRV.Expiration_Date >= SLC.Post_Date) WHERE SLC.Post_Date>='2015-01-01'
)
SELECT *
FROM (
SELECT * FROM Sales_CTE
) as s
PIVOT
(
SUM(Amount)
FOR [MonthSold] IN ("15-Jan","15-Feb","15-Mar","15-Apr","15-May","15-Jun","15-Jul","15-Aug","15-Sep","15-Oct","15-Nov","15-Dec","16-Jan","16-Feb","16-Mar","16-Apr","16-May","16-Jun","16-Jul","16-Aug","16-Sep","16-Oct","16-Nov","16-Dec")
)AS pvt order by Employee_No asc
GO