古いバージョンの 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 句に移動できるかどうかはテストしていません。それが機能する場合は、余分な列を返す必要はありませんが、そのクエリは非常に奇妙に見えます。)もう 1 つのオプション (余分な列を省略する) は、このクエリを (インライン ビューとして) 別のクエリでラップすることです。
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