簡體   English   中英

Oracle查詢-選擇頭條記錄

[英]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

在Oracle中,可以使用LAST函數簡化此過程。

select max(id) keep (dense_rank last order by revision),
       name,
       max(revision)
from table
group by name;

演示版

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM