WITH t1 AS (SELECT a.id,
AVG(standard_qty) std_avg,
AVG(poster_qty) pos_avg,
AVG(glossy_qty) gloss_avg
FROM accounts a
JOIN orders o
ON a.id = o.account_id
GROUP BY 1),
t2 AS (SELECT MAX(std_avg) max_std_avg,
MAX(pos_avg) max_pos_avg ,
MAX(gloss_avg) max_gloss_avg
FROM t1)
SELECT std_id , max_std_avg, pos_id , max_pos_avg, glos_id , max_gloss_avg
FROM(SELECT
(SELECT id std_id FROM t1,t2 WHERE std_avg = max_std_avg),
(SELECT id pos_id FROM t1,t2 WHERE pos_avg = max_pos_avg),
(SELECT id glos_id FROM t1,t2 WHERE gloss_avg =max_gloss_avg)
)foo ,t1,t2
Run Code Online (Sandbox Code Playgroud)
结果:
std_id | max_std_avg| pos_id | max_pos_avg | glos_id | max_gloss_avg
-----------------------------------------------------------------------
1341 | 1891.7777 | 4251 | 2184.4615 | 4211 | 523.258
1341 | 1891.7777 | 4251 | 2184.4615 | 4211 | 523.258
'
'
'
'
'
1341 | 1891.7777 | 4251 | 2184.4615 | 4211 | 523.258
(350 ROWS)
Run Code Online (Sandbox Code Playgroud)
但是,输出应该只有 1 个单行:
std_id | max_std_avg| pos_id | max_pos_avg | glos_id | max_gloss_avg
-----------------------------------------------------------------------
1341 | 1891.7777 | 4251 | 2184.4615 | 4211 | 523.258
Run Code Online (Sandbox Code Playgroud)
如果有人能解释原因,我将不胜感激?谢谢。
在最后一个外部查询中,您foo使用t1and交叉连接t2,而您只需要(和使用)来自fooand 的列t2。
所以删除t1连接:
WITH
...
SELECT
FROM (
...
) foo, t2 ;
Run Code Online (Sandbox Code Playgroud)
整个外部查询可以进一步简化,因为t2在三个子查询和主查询中,您实际上并不需要使用四次。您可以使用一次,并且仍然可以将其加入t1三次:
WITH t1 AS ...,
t2 AS ...
SELECT std.id AS std_id, t2.max_std_avg,
pos.id AS pos_id, t2.max_pos_avg,
gloss.id AS gloss_id, t2.max_gloss_avg
FROM t2
JOIN t1 AS std ON std .std_avg = t2.max_std_avg
JOIN t1 AS pos ON pos .pos_avg = t2.max_pos_avg
JOIN t1 AS gloss ON gloss.gloss_avg = t2.max_gloss_avg
;
Run Code Online (Sandbox Code Playgroud)
另一种获得相同结果但格式略有不同(3 行而不是 1 行)的方法是根本不使用连接,而是使用更多的窗口函数。你也可以:
accounts从第一个 CTE 中删除。如果有FOREIGN KEYfrom ordersto accounts,结果将是相同的。新查询:
WITH t1 AS (SELECT account_id,
AVG(standard_qty) AS std_avg,
AVG(poster_qty) AS pos_avg,
AVG(glossy_qty) AS gloss_avg,
MAX(AVG(standard_qty)) OVER () AS max_std_avg,
MAX(AVG(poster_qty)) OVER () AS max_pos_avg ,
MAX(AVG(glossy_qty)) OVER () AS max_gloss_avg
FROM orders o
GROUP BY account_id)
SELECT t1.*,
CASE WHEN std_avg = max_std_avg
THEN 'max_std_avg' ELSE NULL
END AS std_result,
CASE WHEN pos_avg = max_pos_avg
THEN 'max_pos_avg' ELSE NULL
END AS pos_result,
CASE WHEN gloss_avg = max_gloss_avg
THEN 'max_gloss_avg' ELSE NULL
END AS gloss_result
FROM t1
WHERE std_avg = max_std_avg
OR pos_avg = max_pos_avg
OR gloss_avg = max_gloss_avg ;
Run Code Online (Sandbox Code Playgroud)