Postgresql

什麼情況下需要在間隙和島嶼中計數(x 或 null)?

  • January 8, 2019

這個答案中,Erwin Brandstetter 說:

count(step OR NULL) OVER (ORDER BY date)是最短的語法,也適用於 Postgres 9.3 或更早版本。count()只計算非空值。在現代 Postgres 中,更簡潔、等效的語法是:

count(step) FILTER (WHERE step) OVER (ORDER BY date)

我不確定為什麼count(step OR NULL)是首選。在我的查詢中,我執行以下操作。我在保持語法的同時重命名了我的變數以匹配他的變數。

CASE WHEN lag(id_type) OVER (ORDER BY date) <> id_type THEN 1 END AS step

我們正在計算它返回的值。請注意,case 只能返回 1 或 null。

  • 如果兩者不相等,則返回 1。
  • 如果它們相等,則返回不計入的 null。

歐文的回答是:

這假設涉及的列是**NOT NULL**. 否則你需要做更多。

所以我更加困惑。添加count(step OR NULL)保護我們查詢的內容有什麼意義?

任何人都可以打破這一點,並可能展示兩個帶有數據的範例,其中只有一個 - 一個 -count(x OR NULL)有效嗎?

據我所知,這都是關於處理false not null。有程式碼和一些關於香草的背景知識count():案例count(x OR NULL)的關鍵是什麼時候x=false

  1. **香草count()**抓住了錯誤。這將返回 1。
SELECT count(x)
FROM ( VALUES (false) ) AS t(x);
  1. CASEfold ,將 false折疊為 null ,與 false 不同,將其count()排除在外。這將返回 0。
SELECT count(x)
FROM ( VALUES (CASE WHEN false THEN 1 END) ) AS t(x);
  1. 短路方法評估false OR null,因此null排除count()。這將返回 0。
SELECT count(x OR NULL)
FROM ( VALUES (false) ) AS t(x);
  1. **FILTER**方法,將 x 評估為布爾值。跳過假值和空值,將其他所有內容(真)發送到count(). 這將返回 0。
SELECT count(x) FILTER (WHERE x)
FROM ( VALUES (false) ) AS t(x);

結論

在我的範例中,我使用了 method 2,Erwin 使用 method3既不是修復也不是更好;既不是更優化也不是更快。

這都是關於 NULL 處理的。該表達式的lag(id_type) OVER (ORDER BY date) <> id_type計算結果為布爾值,可以TRUEFALSENULL。如果左操作數或右操作數為 NULL,我們得到 NULL。可以通過多種方式在任一側引入 NULL:

  • 沒有上一個(或下一個或相關情況下類似的)行。
  • 基礎表中的列可以為 NULL。
  • AnOUTER JOIN引入 NULL(未找到匹配行)。
  • 涉及一個可以計算為 NULL 的表達式。

有多種方法可以將三值邏輯折疊為兩種情況。CASE語句、表達式等。OR相關答案及詳細資訊:

這是所涉及技術的比較,以及(更新的)基準。基本上,它們都執行相同的操作,這是一種廉價的操作。FILTER在更新的基準測試中,引入 Postgres 9.4的聚合子句似乎更快一些:

沒有案例wherein only one of them works,這些技術是可以互換的。確切地計算或求和的內容取決於設置和要求的詳細資訊。在這種情況下,我們只計算TRUE- 只要基礎表或查詢產生所有非空值(第一行的極端情況有待討論)。

而這種情況只需要簡單的比較。相關案例需要更仔細地查看上一個或下一個值。然後提供一個預設值作為lag()or的第三個參數可能會派上用場lead()

引用自:https://dba.stackexchange.com/questions/167096