我有一个很长的公用表表达式(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
或者我只是想一次性做太多事情?
答案 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