2009-12-14 133 views
0

T-SQL查询支点假如你有这个表:组合两个在一个

CREATE TABLE Records 
(
    RecordId  int IDENTITY(1,1) NOT NULL, 
    CreateDate  datetime   NOT NULL, 
    IsSpecial  bit    NOT NULL 
    CONSTRAINT PK_Records PRIMARY KEY(RecordId) 
) 

现在的报告需要创建其中总记录和全部特别记录按月细分。我可以单独使用这两个查询:

--  TOTAL RECORDS PER MONTH 
SELECT January, February, March, April, May, June, 
    July, August, September, October, November, December 
FROM (
    SELECT RecordId, DATENAME(MONTH, CreateDate) AS RecordMonth 
    FROM dbo.Records 
) AS SourceTable 
PIVOT (
    COUNT(RecordId) FOR RecordMonth IN (January, February, March, April, May, June, 
    July, August, September, October, November, December) 
) AS PivotTable; 

--  TOTAL SPECIAL RECORDS PER MONTH 
SELECT January, February, March, April, May, June, 
    July, August, September, October, November, December 
FROM (
    SELECT RecordId, DATENAME(MONTH, CreateDate) AS RecordMonth 
    FROM dbo.Records 
    WHERE IsSpecial = 1 
) AS SourceTable 
PIVOT (
    COUNT(RecordId) FOR RecordMonth IN (January, February, March, April, May, June, 
    July, August, September, October, November, December) 
) AS PivotTable; 

结果可能是这样的:

    Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec 
total    0  0 2  2  1  0  0 1  2  1  2 4 
total special  0  0 1  0  1  0  0 0  0  0  0 2 

是否有可能这两个查询合并成一个更高效的查询?

+0

结合如何?你能给出一个结果集的例子吗? – JeffO 2009-12-14 20:23:12

回答

3

我会做这样的:

SELECT 
    CASE SQ.total_type 
      WHEN 1 THEN 'total special' 
      WHEN 2 THEN 'total expensive' 
      ELSE 'total' 
    END AS total_type, 
    SUM(CASE WHEN MONTH(R.CreateDate) = 1 THEN 1 ELSE 0 END) AS January, 
    SUM(CASE WHEN MONTH(R.CreateDate) = 2 THEN 1 ELSE 0 END) AS February, 
    SUM(CASE WHEN MONTH(R.CreateDate) = 3 THEN 1 ELSE 0 END) AS March, 
    ... 
FROM 
    dbo.Records R 
INNER JOIN 
    (
      SELECT 0 AS total_type UNION ALL -- All 
      SELECT 1 UNION ALL     -- IsSpecial 
      SELECT 2       -- IsExpensive 
    ) AS SQ ON 
    (R.IsSpecial | (R.IsExpensive * 2)) & SQ.total_type = SQ.total_type 
GROUP BY 
    SQ.total_type 
ORDER BY 
    SQ.total_type DESC 
+0

好点。不要使用PIVOT ... – gbn 2009-12-14 20:27:06

+0

我的查询是错误的atm虽然...正在修复 – 2009-12-14 20:30:04

+0

好吧,我认为它现在正常工作 – 2009-12-14 20:33:38

2

只能有每一个支点合计(COUNT(RecordId)),所以你要做的就是结合成一个结果集与UNION ALL用合适的额外的列来识别每个枢轴。

否则,你就没有办法区分两种不同的聚集在枢轴

+0

我喜欢用Common Table Express来做到这一点。 – 2009-12-14 20:27:48

0

感谢汤姆的解决方案,即回答我的问题支点。

对我来说太糟糕了我错了。对于我的问题,我现在的感觉会更好用普通的分组这样的查询,而不是:

SELECT DATENAME(MONTH, CreateDate) AS Month, 
    COUNT(*) AS Total, 
    SUM(CASE 
     WHEN IsSpecial = 1 THEN 1 
     ELSE 0 
    END) AS TotalSpecial, 
    SUM(CASE 
     WHEN IsExpensive = 1 THEN 1 
     ELSE 0 
    END) AS TotalExpensive 
FROM Records 
GROUP BY DATENAME(MONTH, CreateDate); 

然后所有剩下要做的就是它们出现之前转动的结果。很高兴知道呃?