我需要一个SQL查询来获取每个月的所有销售额,但如果没有销售额,那么说第3个月应该显示为0。
我目前有这个SQL:
DECLARE @From date
DECLARE @To date
DECLARE @StyleID int
DECLARE @CustomerID int
DECLARE @ColorID int
DECLARE @ClientID int
DECLARE @DataTypeID INT
SET @ColorID = 102
SET @DataTypeID = 3
SELECT
Months.MonthNr,
CONCAT(Months.MonthName_EN,' ',YEAR(Orders.Created)) AS WeekBegining
,DataTypes.DataType
,SUM(XS_1218) as XS_1218
,SUM(S_23) as S_23
,SUM(M_45) as M_45
,SUM(L_67) as L_67
,SUM(XL_811) as XL_811
,SUM(XXL) as XXL
,SUM([1Size]) as [1Size]
,SUM(XS_1218)+SUM(S_23)+SUM(M_45)+SUM(L_67)+SUM(XL_811)+SUM(XXL)+SUM([1Size]) as Total
FROM
OrdersData
LEFT JOIN
DataTypes ON DataTypes.ID = DataTypeID
LEFT JOIN
Orders ON Orders.ID = OrdersID
LEFT JOIN
Months ON Months.MonthNr = MONTH(Orders.Created)
WHERE
(((@From is null) OR (@To is null)) OR (Orders.Created BETWEEN @From AND @To)) AND -- Period Filter
((@StyleID is null) OR (@StyleID = OrdersData.StyleID)) AND -- Style Filter
((@CustomerID is null) OR (@CustomerID = OrdersData.CustomerID)) AND -- Customer Filter
((@ColorID is null) OR (@ColorID = OrdersData.ColorID)) AND -- Color Filter
((@ClientID is null) OR (@ClientID = Orders.ClientID)) AND -- Client Filter
((@DataTypeID is null) OR (@DataTypeID = OrdersData.DataTypeID)) AND
YEAR(Orders.Created) = 2013
GROUP BY
DataTypes.DataType, YEAR(Orders.Created), MONTH(Orders.Created),
Months.MonthNr, Months.MonthName_EN --DataTypes.DataType
ORDER BY
DataTypes.DataType, YEAR(Orders.Created), MONTH(Orders.Created),
Months.MonthNr, Months.MonthName_EN ASC
,结果如下:
我需要1,2,3个月全部为0
感谢GarethD只是编辑你的代码它有几个错误:) 溶剂:
脚本:
DECLARE @From date
DECLARE @To date
DECLARE @StyleID int
DECLARE @CustomerID int
DECLARE @ColorID int
DECLARE @ClientID int
DECLARE @DataTypeID INT
SET @ColorID = 102
SET @DataTypeID = 3
SET @From = '2013-01-01'
SET @To = '2014-12-01'
;WITH Data AS
( SELECT MONTH(Orders.Created) AS MonthCreated
,YEAR(Orders.Created) AS YearCreated
,SUM(XS_1218) as XS_1218
,SUM(S_23) as S_23
,SUM(M_45) as M_45
,SUM(L_67) as L_67
,SUM(XL_811) as XL_811
,SUM(XXL) as XXL
,SUM([1Size]) as [1Size]
,SUM(XS_1218)+SUM(S_23)+SUM(M_45)+SUM(L_67)+SUM(XL_811)+SUM(XXL)+SUM([1Size]) AS Total
FROM OrdersData
LEFT JOIN DataTypes
ON DataTypes.ID = DataTypeID
LEFT JOIN Orders
ON Orders.ID = OrdersID
WHERE
(((@From is null) OR (@To is null)) OR (Orders.Created BETWEEN @From AND @To)) AND -- Period Filter
((@StyleID is null) OR (@StyleID = OrdersData.StyleID)) AND -- Style Filter
((@CustomerID is null) OR (@CustomerID = OrdersData.CustomerID)) AND -- Customer Filter
((@ColorID is null) OR (@ColorID = OrdersData.ColorID)) AND -- Color Filter
((@ClientID is null) OR (@ClientID = Orders.ClientID)) AND -- Client Filter
((@DataTypeID is null) OR (@DataTypeID = OrdersData.DataTypeID))
GROUP BY YEAR(Orders.Created),MONTH(Orders.Created) --DataTypes.DataType
)
SELECT m.MonthNr,
m.MonthYear,
WeekBegining = CONCAT(m.MonthName_EN,' ',ISNULL(YearCreated,MonthYear)),
XS_1218 = ISNULL(d.XS_1218, 0),
S_23 = ISNULL(d.S_23, 0),
M_45 = ISNULL(d.M_45, 0),
L_67 = ISNULL(d.L_67, 0),
XL_811 = ISNULL(d.XL_811, 0),
XXL = ISNULL(d.XXL, 0),
[1Size] = ISNULL(d.[1Size], 0),
Total = ISNULL(d.Total, 0)
FROM Months AS m
LEFT JOIN Data AS d
ON d.MonthCreated = m.MonthNr AND d.YearCreated = m.MonthYear
WHERE m.MonthYear BETWEEN YEAR(@From) AND YEAR(@To)
ORDER BY m.MonthYear,m.MonthNr
月份表:
CREATE TABLE [dbo].[Months](
[ID] [int] IDENTITY(1,1) NOT NULL,
[MonthNr] [int] NOT NULL,
[MonthName_EN] [nvarchar](150) NOT NULL,
[MonthYear] [int] NOT NULL,
CONSTRAINT [PK_Months] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
使用值填充月表,它就像魅力一样
结果:
希望这有助于某人
答案 0 :(得分:1)
您应该将FROM
子句与Months
和LEFT JOIN
一起启动到其他表格。
像下面这样的东西?
--previous code
FROM Months
LEFT JOIN Orders ON Months.MonthNr = MONTH(Orders.Created)
LEFT JOIN DataTypes ON Orders.ID = OrdersID
LEFT JOIN OrdersData ON DataTypes.ID = DataTypeID
--next code
答案 1 :(得分:1)
看起来您需要从Months
表格中进行选择,然后选择加入数据,而不是相反,
WITH Data AS
( SELECT MONTH(Orders.Created) AS MonthCreated
,DataTypes.DataType
,SUM(XS_1218) as XS_1218
,SUM(S_23) as S_23
,SUM(M_45) as M_45
,SUM(L_67) as L_67
,SUM(XL_811) as XL_811
,SUM(XXL) as XXL
,SUM([1Size]) as [1Size]
,SUM(XS_1218)+SUM(S_23)+SUM(M_45)+SUM(L_67)+SUM(XL_811)+SUM(XXL)+SUM([1Size]) AS Total
FROM OrdersData
LEFT JOIN DataTypes
ON DataTypes.ID = DataTypeID
LEFT JOIN Orders
ON Orders.ID = OrdersID
WHERE
(((@From is null) OR (@To is null)) OR (Orders.Created BETWEEN @From AND @To)) AND -- Period Filter
((@StyleID is null) OR (@StyleID = OrdersData.StyleID)) AND -- Style Filter
((@CustomerID is null) OR (@CustomerID = OrdersData.CustomerID)) AND -- Customer Filter
((@ColorID is null) OR (@ColorID = OrdersData.ColorID)) AND -- Color Filter
((@ClientID is null) OR (@ClientID = Orders.ClientID)) AND -- Client Filter
((@DataTypeID is null) OR (@DataTypeID = OrdersData.DataTypeID)) AND
Orders.Created >= '20130101' AND
Orders.Created < '20140101'
GROUP BY DataTypes.DataType,MONTH(Orders.Created) --DataTypes.DataType
)
SELECT Months.MonthNr,
WeekBegining = CONCAT(Months.MonthName_EN,' ',YEAR(Orders.Created)),
XS_1218 = ISNULL(d.XS_1218, 0),
S_23 = ISNULL(d.S_23, 0),
M_45 = ISNULL(d.M_45, 0),
L_67 = ISNULL(d.XS_L_671218, 0),
XL_811 = ISNULL(d.XL_811, 0),
XXL = ISNULL(d.XXL, 0),
[1Size] = ISNULL(d.[1Size], 0),
Total = ISNULL(d.Total, 0)
FROM Months AS m
LEFT JOIN Data AS d
ON d.CreatedMonth = m.MonthNr;
这样,即使没有订单数据,您也会显示月份。
注意,我已更改此行:
YEAR(Orders.Created) = 2013
要
Orders.Created >= '20130101' AND
Orders.Created < '20140101'
后者为sargable,可以利用Created
列上的索引,而后者则不会,也不会。
此外,它取决于您实际调用此查询的方式,但您可能需要考虑使用OPTION (RECOMPILE)
,这可能允许更好的执行计划,查询将在运行时编译,并且谓词如下:
(@DataTypeID is null) OR (@DataTypeID = OrdersData.DataTypeID)
可以评估您传递的@DataTypeID
的具体值。如果没有这个,你总会得到一个表扫描,而有了它,你可能会在@DataTypeID
不为空的时候找到索引搜索。