[英]Oracle query - select top records
假設下表:
ID Name Revision
--- ----- --------
1 blah 0
2 yada 1
3 blah 1
4 yada 0
5 blah 2
6 blah 3
如何獲得兩個修訂版本最高的記錄,一個是“ blah”,一個是“ yada”(修訂版為3,blad yada為1)? 就像是:
ID Name Revision
--- ----- --------
6 blah 3
2 yada 1
此外,一旦檢索到這些記錄,如何獲得其余的記錄(按名稱和修訂順序排序)?
我正在嘗試創建一個主從視圖,其中主記錄是最新修訂,詳細信息包括先前修訂。
基本上,使用聚合函數MAX()
:
SELECT "Name", MAX("Revision") AS max_revison
FROM tbl
WHERE "Name" IN ('blah', 'yada');
GROUP BY "Name"
ORDER BY "Name"; -- ordering by revision would be pointless;
如果您需要從該行中獲得更多列 ,則有幾種方法。 一種方法是將上述子查詢重新加入基表中:
SELECT t.*
FROM (
SELECT "Name", max("Revision") AS max_revison
FROM tbl
WHERE "Name" IN ('blah', 'yada');
GROUP BY "Name"
) AS sub
JOIN tbl AS t ON t."Revision" = sub.max_revison
AND t."Name" = sub."Name"
ORDER BY "Name";
一般情況下,這有每產量超過一排的潛力"Name"
-如果“版本”是不是(按“姓名”)是唯一的。 您將必須定義如何從一組共享相同最大“修訂”值的對等方中選擇one
-決勝局。
另一種方法是使用NOT EXISTS
,排除具有更大同位體(可能更快)的行:
SELECT t.*
FROM tbl AS t
WHERE "Name" IN ('blah', 'yada')
AND NOT EXISTS (
SELECT 1
FROM tbl AS t1
WHERE t1."Name" = t."Name"
AND t1."Revision" > t."Revision"
)
ORDER BY "Name";
或者,您可以將CTE與分析功能(窗口功能)一起使用:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY "Name" ORDER BY "Revision" DESC) AS rn
FROM tbl
WHERE "Name" IN ('blah', 'yada')
)
SELECT *
FROM cte
WHERE rn = 1;
最后一個稍有不同:保證每個"Name"
一行。 如果您不使用更多ORDER BY
項目,則在出現平局的情況下將選擇任意行。 如果要所有對等節點,請改用RANK()
。
此方法將為每個名稱選擇具有該名稱最大修訂號的行。 結果將是您在帖子中尋找的確切輸出。
SELECT *
FROM tbl a
WHERE a.revision = (select max(revision) from tbl where name = a.name)
ORDER BY a.name
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.