1

这应该很容易,但我就是找不到答案(我会把它归咎于我已经进行了近 14 个小时的 SQL 编码这一事实)。

我有一个名为 report 的表,其中包含“Label”字段和“ReportYear”字段。我知道我有三个可能的“标签”值,但并非每个标签每年都有一个条目。

我可以选择一个不同的标签列表,我得到:

'Regular'
'Special'
'None'

在这里进行一些手动数据选择,我知道 2011 和 2010 有 0 个带有“特殊”标签的条目,但我需要一个查询来将这些信息汇总在一起,以便它出来:

'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?

我的大脑被炸了。

帮助?

4

1 回答 1

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通过将整个查询参数化为接受BeginYearEndYear类似的东西来消除子查询。或者,您可以Min(ReportYear), Max(ReportYear)从表中获取,并假设您在该列上有一个索引,它可能能够将其转换为搜索(可​​能需要两个单独的查询来获得它),然后使用数字表或在- fly numbers 表以生成它们之间的年份序列。

进行这两项更改后,查询的性能将大大提高。

于 2013-04-27T00:07:24.643 回答