0

我在 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 子句中放置一个数组或类似的东西吗?谢谢。

4

3 回答 3

1

我想你可能想使用 OUTER JOIN。使用外连接,查询将返回 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)
于 2012-04-04T17:17:05.103 回答
1

它在删除 WHERE 子句并在计数聚合中进行所有过滤后起作用。

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)
于 2012-04-05T20:38:52.753 回答
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)
于 2012-04-05T14:59:37.033 回答