使用聚合的T-SQL多层CTE查询

时间:2016-05-04 14:48:49

标签: sql-server jointable

我有一个很长的公用表表达式(CTE)查询,它试图计算每个用户的平均得分和组平均得分之间的百分比差异。

我希望我的多层CTE查询能够过滤并减少大量记录,直至下表:

A   Account Bob
M   Manager Sandy
S   Sales

我的问题是获取$ ccmake . 列,以便我可以执行UserID Tag UserAvg GroupAvg PercentDifference 1 Cat 72.50 73 -0.68 2 Cat 75.50 73 3.36 3 Cat 75 73 2.70 4 Cat 73.25 73 0.34 5 Cat 52.3333 73 -32.97 6 Cat 86.25 73 16.64 计算。

说明我正在使用的当前方法;这是我的CTE查询摘要:

GroupAvg

足够简单;正确?

请注意,我已将% Difference硬编码为WITH -- select 1st 3 columns UserScores AS (select UserID, Tag, Score FROM {multiple-table} WHERE Tag = 'Cat'), -- add UserAvg column by grouping records ScoreAverages AS (select UserID, Tag, AVG(Score) AS UserAvg GROUP BY UserID, Tag FROM UserScores), -- calculate GroupAvg GroupAverage AS (select AVG(UserAvg) AS GroupAvg FROM ScoreAverages), -- calculate % difference PercentDiff AS (select UserID, Tag, UserAvg, 73 AS GroupAvg, (((UserAvg-73)/((UserAvg+73)/2))*100) AS PercentDifference FROM ScoreAverages ) -- do something with results select * from PercentDiff 值。我不确定如何构建所需的sql查询,这将允许我从73转到GroupAvg表。

是否可以在SELECT语句中执行SELECT?我不是在寻找以下内容:

ScoreAverages

或者我只是想一次性做太多事情?

3 个答案:

答案 0 :(得分:4)

是的,它被称为子选择:

SELECT Column1, Column2, (SELECT QUERY THAT GETS GROUP AVERAGE) AS GroupAverage, Column3
FROM ...

要在另一列的计算中使用子选择的结果,您可以重复子选择:

SELECT Column1, Column2, (SELECT QUERY THAT GETS GROUP AVERAGE) AS GroupAverage, (Column3 - (SELECT QUERY THAT GETS GROUP AVERAGE)) AS Column4
FROM ...

或者您可以像引用外部查询中的任何其他列或后续CTE一样引用它:

WITH CTE1 AS (SELECT Column1, Column2, (SELECT QUERY THAT GETS GROUP AVERAGE) AS GroupAverage
FROM ...)
  , CTE2 AS (SELECT *, Column3-GroupAverage) AS Column4
  FROM CTE1
  JOIN ...

答案 1 :(得分:3)

有可能,如Tab Alleman的回答所示,但在你的情况下,它没有必要。由于您已经计算了cte链中的GroupAverage,因此可以在最终查询中使用它。由于;WITH -- select 1st 3 columns UserScores AS ( select UserID, Tag, Score FROM {multiple-table} WHERE Tag = 'Cat'), -- add UserAvg column by grouping records ScoreAverages AS ( select UserID, Tag, AVG(Score) AS UserAvg FROM UserScores GROUP BY UserID, Tag), -- calculate GroupAvg GroupAverage AS ( select AVG(UserAvg) AS GroupAvg FROM ScoreAverages), -- calculate % difference PercentDiff AS ( select UserID, Tag, UserAvg, GroupAvg, (((UserAvg-GroupAvg)/((UserAvg+GroupAvg)/2))*100) AS PercentDifference FROM ScoreAverages CROSS JOIN GroupAverage) -- do something with results select * from PercentDiff 只包含一行,您只需添加一个CROSS JOIN:

{{1}}

答案 2 :(得分:1)

我只是认为你可以用一个像这样的单一的cte来做到这一点。

;WITH UserAverages AS
(
    SELECT  UserID,
            Tag,
            AVG(Score) AS UserAvg,
            AVG(AVG(Score)) OVER () AS GroupAvg
    FROM    {multiple-table}
    WHERE   Tag = 'Cat'
    GROUP BY UserID, Tag
)
SELECT  UserID,
        Tag,
        UserAvg,
        GroupAvg,
        (((UserAvg-GroupAvg)/((UserAvg+GroupAvg)/2))*100) AS PercentDifference
FROM    UserAverages