我在ssrs报告中使用以下查询。
Declare @Year int = 2012
Declare @ProdType_ID int = 1
SELECT
MONTH(Ord.OrdDate) AS 'MONTH',
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) THEN 1 END) as Order1,
COUNT(CASE WHEN @Year-1 = YEAR(Ord.OrdDate) THEN 1 END) as 'Order2'
FROM
(
select 1 as number
union
select 2
union
select 3
union
select 4
union
select 5
union
select 6
union
select 7
union
select 8
union
select 9
union
select 10
union
select 11
union
select 12
) as months
JOIN Ord on Number = Month(Ord.OrdDate)
JOIN Prod ON Ord.Prod_ID = Prod.ID
JOIN ProdType ON Prod.ProdType_ID = ProdType.ID
WHERE @ProdType_ID = ProdType.ID
GROUP BY months.number, Month(Ord.OrdDate)
这会返回一个包含正确分组的表格,但未显示尚未记录或未记录的月份这一事实除外。我希望每个月都能显示,即使它尚未通过,我希望他们的订单价值为零。
我是否可以通过某种方式在FROM子句中放置数组或类似内容? 感谢。
答案 0 :(得分:1)
我想你可能想要使用OUTER JOIN。 使用 left 外部联接,查询将返回FROM子句中“左表”中具有满足任何WHERE条件的行的所有行。其他表中的列值将为NULL。因此,如果需要特殊处理NULL,您可能需要在select语句中使用的列值周围添加ISNULL函数。
此MSDN文章Using Outer Joins包含更完整的信息。
我使用左外连接重写了你的查询。你可能需要对case语句做一些额外的工作,但可能不需要 - 如果参数值为NULL,YEAR函数将返回NULL,我认为逻辑可以成立。
Declare @Year int = 2012
Declare @ProdType_ID int = 1
SELECT
MONTH(Ord.OrdDate) AS 'MONTH',
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) THEN 1 END) as Order1,
COUNT(CASE WHEN @Year-1 = YEAR(Ord.OrdDate) THEN 1 END) as 'Order2'
FROM
(
select 1 as number
union
select 2
union
select 3
union
select 4
union
select 5
union
select 6
union
select 7
union
select 8
union
select 9
union
select 10
union
select 11
union
select 12
) as months
LEFT OUTER JOIN Ord on Number = Month(Ord.OrdDate)
LEFT OUTER JOIN Prod ON Ord.Prod_ID = Prod.ID
LEFT OUTER JOIN ProdType ON Prod.ProdType_ID = ProdType.ID
WHERE @ProdType_ID = ProdType.ID
GROUP BY months.number, Month(Ord.OrdDate)
答案 1 :(得分:1)
在删除WHERE子句并在count聚合中执行所有过滤后,它才起作用。
SELECT
MONTH(Ord.OrdDate) AS 'Month',
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) and @ProdType_ID = ProdType.ID THEN 1 END) AS Order1,
COUNT(CASE WHEN @Year-1 = YEAR(Ord.OrdDate) and @ProdType_ID = ProdType.ID THEN 1 END) AS Order2
FROM
(
SELECT 1 AS Number
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
UNION
SELECT 7
UNION
SELECT 8
UNION
SELECT 9
UNION
SELECT 10
UNION
SELECT 11
UNION
SELECT 12
) AS Months
LEFT OUTER JOIN Ord ON Number = MONTH(Ord.OrdDate)
LEFT OUTER JOIN Prod ON Ord.Prod_ID = Prod.ID
LEFT OUTER JOIN ProdType ON Prod.ProdType_ID = ProdType.ID
GROUP BY Months.Number, MONTH(Ord.OrdDate)
答案 2 :(得分:0)
如果还使用LEFT JOIN
。但我建议使用Tally表来获取月份。这将适用于sql server 2005 +:
Declare @Year int = 2012
Declare @ProdType_ID int = 1
;WITH Months ( Number ) AS
(
SELECT 1 UNION ALL
SELECT 1 + Number FROM Months WHERE Number < 12
)
SELECT
MONTH(Ord.OrdDate) AS 'MONTH',
COUNT(CASE WHEN @Year = YEAR(Ord.OrdDate) THEN 1 END) as Order1,
COUNT(CASE WHEN @Year-1 = YEAR(Ord.OrdDate) THEN 1 END) as 'Order2'
FROM
Months
LEFT JOIN Ord on Number = Month(Ord.OrdDate)
LEFT JOIN Prod ON Ord.Prod_ID = Prod.ID
LEFT JOIN ProdType ON Prod.ProdType_ID = ProdType.ID
WHERE @ProdType_ID = ProdType.ID
GROUP BY months.number, Month(Ord.OrdDate)