我有一张表,其中包括两列,一列用于开始日期,另一列用于结束日期。我需要编写一个查询,该查询将返回一年中每个月的列,如果月份在0之间,则该列的值为1。 PIVOT语句似乎是我在这里寻找的,但从最好的我可以告诉PIVOT子句寻找匹配值,而不是检查值是否在两个其他之间。 PIVOT子句在这里是正确的构造,还是我需要分解并编写12个案例语句然后汇总它们?
答案 0 :(得分:2)
我想我在这里得到了解决方案。有3个基本步骤:
为了获得12个日期,每个月一个,我使用一些递归式的WITH语句来创建一个包含12列日期的1列的临时表:
WITH months (date) AS (
SELECT GETDATE() AS date
UNION ALL
SELECT
DATEADD(MONTH,1,date)
FROM months
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12)
从这里我可以CROSS JOIN这个临时表与表格,我真正关心的信息。然后我使用WHERE日期BETWEEN开始和结束来过滤掉那些不属于那个月的条目。所以像这样:
SELECT other.Title, MONTH(months.date) CROSS JOIN other
WHERE months.date BETWEEN other.start AND other.end
在这一步中,我们必须小心只选择结果中明确需要的列,或者使用PIVOT语句聚合的列。
最后,我们必须调整结果:
PIVOT (MAX(PID) FOR date IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]))
因此,结果查询可能类似于:
WITH months (date) AS (
SELECT GETDATE() AS date
UNION ALL
SELECT
DATEADD(MONTH,1,date)
FROM months
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12)
SELECT Title,
[1] AS January,
[2] AS February,
[3] AS March,
[4] AS April,
[5] AS May,
[6] AS June,
[7] AS July,
[8] AS August,
[9] AS September,
[10] AS October,
[11] AS November,
[12] AS December
FROM
(
SELECT other.Title,MONTH(months.date)
CROSS JOIN other
WHERE months.date BETWEEN other.startDate AND other.endDate
) AS subquery
PIVOT (MAX(PID) FOR date IN
([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) AS p
我已经删除了我所需要的所有其他复杂性以加入我需要的其他信息,所以这实际上不是我写的查询,但它应该封装我用来获得结果的基本查询结构因为我需要它。
答案 1 :(得分:0)
我会选择12个案例陈述。
这实际上是我在回去之前勾勒出的解决方案,看到你在其中提到了你的问题。
答案 2 :(得分:0)