这应该很简单,但我无法找到答案(我会因为我已经编写了近14个小时的SQL编码而将其归咎于此。)
我有一个名为report的表,其中包含“Label”字段和“ReportYear”字段。我知道我有三个可能的“标签”值,但不是每个标签都会有每年的条目。
我可以选择一个不同的标签列表,我得到:
'Regular'
'Special'
'None'
在这里做一些手动数据选择,我知道2011年和2010年有0个标签为'Special'的条目,但我需要一个查询来将这些信息整合在一起,以便它出来:
'Regular' - '2012' - '5'
'Regular' - '2011' - '2'
'Regular' - '2010' - '1'
'Special' - '2012' - '3'
'Special' - '2011' - '0'
'Special' - '2010' - '0'
'None' - '2012' - '10'
'None' - '2011' - '5'
'None' - '2010' - '2'
希望这是有道理的。
我知道我可以SELECT Count(*), Label FROM (SELECT DISTINCT Label FROM Report) t1
......但是呢? LEFT JOIN Report t2 ON t1.Label=t2.Label
? CROSS JOIN
?
我的大脑被炸了。
帮助?
答案 0 :(得分:1)
SELECT
L.Label,
Y.ReportYear,
ReportCount = Count(R.Label)
FROM
(SELECT DISTINCT Label FROM dbo.Report) L
CROSS JOIN (SELECT DISTINCT ReportYear FROM dbo.Report) Y
LEFT JOIN dbo.Report R
ON L.Label = R.Label
AND Y.ReportYear = R.ReportYear
GROUP BY
L.Label,
Y.ReportYear
现在,这并不是很理想,因为你要进行两次全表扫描,只是为了得到标签和年份。
除非我误解了事情,否则在我看来,您应该对Report
表进行规范化,使其具有ReportLabelID
列,然后使用带有不同标签的ReportLabel
表。然后,您可以将ReportLabel
表放在上面DISTINCT
查询的位置。
您还可以通过参数化整个查询来消除ReportYear
子查询,以接受BeginYear
和EndYear
或类似的东西。或者,您可以从表中获取Min(ReportYear), Max(ReportYear)
,并假设您在列上有索引,它可以将其转换为搜索(可能需要两个单独的查询来获取此值),然后使用数字表或即时数字表,以生成它们之间的年份序列。
完成这两项更改后,查询的效果会更好。