SELECT
語句中使用多個集合回傳函數的意外行為問題:
在 SELECT
語句的子句中使用多個傳回集合的函數可能會產生意外的結果,特別是當集合的長度不相等時。 generate_series(1, 3)
和 generate_series(5, 7)
產生交叉連接,而 generate_series(1, 2)
和 generate_series(1, 4)
則不會。這種不一致令人費解。
說明:
關鍵在於PostgreSQL版本差異。 PostgreSQL 10 及更高版本對此的處理方式與早期版本(9.6 及之前版本)不同。
PostgreSQL 10 及更高版本:
PostgreSQL 10 及後續版本將 SELECT
清單中的多個回傳集函數視為 LATERAL ROWS FROM(...)
子句。 這些函數同步執行,較短的集合用 NULL
值填充以匹配最長集合的長度。這確保了完整的交叉連接。 例如:
<code>row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 NULL | 13 | 23 NULL | NULL | 24</code>
PostgreSQL 9.6 及更早版本:
在舊版(9.6 及之前)中,結果集的行計數等於單一函數行計數的最小公倍數 (LCM)。 僅當集合大小不共享公約數時才會發生交叉連接。 使用相同的範例,輸出將是:
<code>row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 1 | 13 | 23 2 | 11 | 24 1 | 12 | 21 2 | 13 | 22 1 | 11 | 23 2 | 12 | 24 1 | 13 | 21 2 | 11 | 22 1 | 12 | 23 2 | 13 | 24</code>
最佳實務:
為了避免意外結果,最好使用 LATERAL
連接或子查詢,而不是直接將多個返回集合的函數放在 SELECT
列表中。這提供了更清晰的控制和可預測的行為。
更多詳細資訊和相關信息,請查閱 PostgreSQL 官方文件:
以上是為什麼 SELECT 子句中的多個返回集合的函數並不總是在 PostgreSQL 中產生交叉連接?的詳細內容。更多資訊請關注PHP中文網其他相關文章!