簡體   English   中英

使用SQL中的窗口函數運行“匹配”總數

[英]Running total of “matches” using a window function in SQL

我想創建一個窗口函數,該函數將計算當前行中字段的值出現在當前行之前的有序分區部分中的次數。 為了使這更具體,假設我們有一個這樣的表:

| id| fruit  | date |
+---+--------+------+
| 1 | apple  |   1  |
| 1 | cherry |   2  |
| 1 | apple  |   3  |
| 1 | cherry |   4  |
| 2 | orange |   1  |
| 2 | grape  |   2  |
| 2 | grape  |   3  |

我們想創建一個像這樣的表(為清楚起見,省略日期列):

| id| fruit  | prior |  
+---+--------+-------+
| 1 | apple  |   0   |
| 1 | cherry |   0   |
| 1 | apple  |   1   |
| 1 | cherry |   1   |
| 2 | orange |   0   |
| 2 | grape  |   0   |
| 2 | grape  |   1   |

請注意,對於id = 1 ,沿着有序分區移動,第一個條目'apple'與任何內容都不匹配(因為隱含的集合為空),下一個水果'cherry'也不匹配。 然后我們再次進入'apple',這是匹配等等。 我在想象SQL看起來像這樣:

SELECT
id, fruit, 
<some kind of INTERSECT?> OVER (PARTITION BY id ORDER by date) AS prior
FROM fruit_table; 

但我找不到任何看起來正確的東西。 FWIW,我正在使用PostgreSQL 8.4。

您可以使用自左連接count()來解決沒有窗口功能而非常優雅的問題:

SELECT t.id, t.fruit, t.day, count(t0.*) AS prior
FROM   tbl t
LEFT   JOIN tbl t0 ON (t0.id, t0.fruit) = (t.id, t.fruit) AND t0.day < t.day
GROUP  BY t.id, t.day, t.fruit
ORDER  BY t.id, t.day
  • 我重命名了日期列day因為date每個SQL標准和PostgreSQL中保留字

  • 我糾正了樣本數據中的錯誤。 他們有你的方式,它沒有檢查出來。 可能會讓人困惑。


如果您要使用window函數來執行此操作,則該方法應該可以工作:

SELECT id, fruit, day
      ,count(*) OVER (PARTITION BY id, fruit ORDER BY day) - 1 AS prior
FROM   tbl
ORDER  BY id, day

如果省略frame_end,則默認為CURRENT ROW。

  • 您有效地計算前幾天有多少行(id, fruit) - 包括當前行。 這就是- 1的用途。

暫無
暫無

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

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