在舊版本的Oracle,之前,我們將返回使用查詢像這樣指定的結果集:
SELECT f.group
, f.recipe
, f.priority
FROM foo f
JOIN (SELECT g.group
, g.recipe
, MAX(g.priority) AS max_priority
FROM foo g
GROUP BY g.group, g.recipe
) m
ON m.group = f.group AND m.recipe = f.recipe
ORDER BY f.group
, m.max_priority DESC
, f.recipe
, f.priority DESC
這種方法適用於沒有分析功能的其他數據庫,如MySQL。
注意:上面的查詢不是NULL安全的,因爲JOIN謂詞將消除組或配方列具有NULL值的行。它可以做成NULL安全的,但它使SQL複雜一點。
SELECT f.group
, f.recipe
, f.priority
FROM foo f
JOIN (SELECT g.group
, g.recipe
, MAX(g.priority) AS max_priority
FROM foo g
GROUP BY g.group, g.recipe
) m
ON (m.group = f.group OR COALESCE(m.group,f.group) IS NULL)
AND (m.recipe = f.recipe OR COALESCE(m.recipe,f.recipe) IS NULL)
ORDER BY f.group
, m.max_priority DESC
, f.recipe
, f.priority DESC
的等效結果也可以在SELECT列表使用相關子查詢獲得的,除了該結果集包含在結果集中一個額外的「MAX_PRIORITY」列。
SELECT f.group
, f.recipe
, f.priority
, (SELECT MAX(g.priority)
FROM foo g
WHERE (g.group = f.group OR COALESCE(g.group,f.group) IS NULL)
AND (g.recipe = f.recipe OR COALESCE(g.recipe,f.recipe) IS NULL)
) AS max_priority
FROM foo f
ORDER BY f.group
, 4 DESC
, f.recipe
, f.priority DESC
(我沒有測試是否是相關子查詢可從SELECT列表中刪除,並完全轉移到ORDER BY子句。如果這樣的工作,我們會消除返回額外的列,但該查詢看起來真的很奇怪。)另一種選擇(省略額外的列)是將此查詢(作爲內嵌視圖)封裝在另一個查詢中。
SELECT e.group
, e.recipe
, e.priority
FROM (
SELECT f.group
, f.recipe
, f.priority
, (SELECT MAX(g.priority)
FROM foo g
WHERE (g.group = f.group OR COALESCE(g.group,f.group) IS NULL)
AND (g.recipe = f.recipe OR COALESCE(g.recipe,f.recipe) IS NULL)
) AS max_priority
FROM foo f
) e
ORDER BY e.group
, e.max_priority DESC
, e.recipe
, e.priority DESC
順便說一句,'group'是一個列的_bad_名稱,如果可能的話儘量避免保留字。 – Ben
@我們的評論是不正確的。以配方asc爲例,前兩行是相反的。 –