如何在T-SQL中将表连接到自身?

时间:2009-06-11 08:12:08

标签: tsql

我有以下查询:

SELECT [ApplicationTitle] AS "ApplicationTitle", 
SUM([Visits]) AS "Visits",
SUM([NewVisits]) AS "NewVisits"
FROM [HeadlineFigures] 
WHERE [DataDate] >= '01/06/2009'
AND [DataDate] < '08/06/2009'
GROUP BY [ApplicationTitle]
ORDER BY [ApplicationTitle]

这将返回7天的数据。我希望在同一个查询中再次使用相同的内容,以便它看起来更像:

SELECT a.[ApplicationTitle] AS "ApplicationTitle", 
SUM(a.[Visits]) AS "Visits",
SUM(b.[Visits]) AS "PVisits",
SUM(a.[NewVisits]) AS "NewVisits"
SUM(b.[NewVisits]) AS "PNewVisits"
FROM [HeadlineFigures] a JOIN [HeadlineFigures] b
ON a.[ApplicationTitle] = b.[ApplicationTitle]
WHERE a.[DataDate] >= '01/06/2009'
AND a.[DataDate] < '08/06/2009'
AND b.[DataDate] >= '01/05/2009'
AND b.[DataDate] < '08/05/2009'
GROUP BY a.[ApplicationTitle]
ORDER BY a.[ApplicationTitle]

但上述查询不正确。我做错了什么?

2 个答案:

答案 0 :(得分:2)

您加入然后聚合,导致错误的聚合。 IE浏览器。如果对于ApplicationTitle,您在第一组中有2条记录,在第二组中有2条记录,则该连接将有4条记录,因此SUM会加倍。您需要先聚合,然后加入:

SELECT a.[ApplicationTitle],
    a.Visits,
    a.NewVisists,
    b.Visits as PVisits,
    b.NewVisits as PNewVisits
    FROM (
    SELECT [ApplicationTitle] AS "ApplicationTitle", 
        SUM([Visits]) AS "Visits",
        SUM([NewVisits]) AS "NewVisits"
        FROM [HeadlineFigures] 
        WHERE [DataDate] >= '01/06/2009'
        AND [DataDate] < '08/06/2009'
        GROUP BY [ApplicationTitle]
    ) AS a JOIN (
    SELECT [ApplicationTitle] AS "ApplicationTitle", 
        SUM([Visits]) AS "Visits",
        SUM([NewVisits]) AS "NewVisits"
        FROM [HeadlineFigures] 
        WHERE [DataDate] >= '01/05/2009'
        AND [DataDate] < '08/05/2009'
        GROUP BY [ApplicationTitle]
    ) AS b ON a.[ApplicationTitle] = b.[ApplicationTitle]
        ORDER BY [ApplicationTitle]

答案 1 :(得分:0)

如果我没有完全错过任何东西,那么你就会把事情弄得太复杂。试试这个:

SELECT [ApplicationTitle] AS "ApplicationTitle",
       SUM(CASE WHEN [DataDate] >= '01/06/2009' AND [DataDate] < '08/06/2009' THEN [Visits] ELSE 0 END) AS "Visits",
       SUM(CASE WHEN [DataDate] >= '01/05/2009' AND [DataDate] < '08/05/2009' THEN  [Visits] ELSE 0 END) AS "PVisits",
       SUM(CASE WHEN [DataDate] >= '01/06/2009' AND [DataDate] < '08/06/2009' THEN [NewVisits] ELSE 0 END) AS "NewVisits",
       SUM(CASE WHEN [DataDate] >= '01/05/2009' AND [DataDate] < '08/05/2009' THEN [NewVisits] ELSE 0 END) AS "PNewVisits",
  FROM [HeadlineFigures]
 WHERE    ([DataDate] >= '01/06/2009' AND [DataDate] < '08/06/2009')
       OR ([DataDate] >= '01/05/2009' AND [DataDate] < '08/05/2009')
 GROUP BY [ApplicationTitle]
 ORDER BY [ApplicationTitle]

编辑:哎呀,我误读了数据范围。 我希望SQL服务器能够在DataDate上使用索引做得很好,否则from子句需要看起来像:

FROM (SELECT * FROM [ApplicationTitle] WHERE [DataDate] >= '01/06/2009' AND [DataDate] < '08/06/2009'
      UNION
      SELECT * FROM [ApplicationTitle] WHERE [DataDate] >= '01/05/2009' AND [DataDate] < '08/05/2009') x