簡短版本,我有一個 SQL 陳述句,如果回傳的行數小于某個值(比如 1000),我只想要結果,否則我想要不同的結果集。當我要扔掉它們時,最好的方法是什么而不產生回傳 1000 行的開銷(如果我使用限制會發生這種情況)?
例如,我想回傳結果
SELECT *
FROM T
WHERE updated_at > timestamp
AND name <= 'Michael'
ORDER BY name ASC
提供最多 1000 個條目,但如果有更多我想回傳
SELECT *
FROM T
ORDER BY name ASC
LIMIT 25
兩個查詢還不錯,但我絕對不想從第一個查詢中取回 1000 條記錄,只是為了折騰它們。
(也很高興使用 Postgres 擴展,但更喜歡 SQL)
--
為了解釋我正在批量重繪 客戶請求的資料,有時客戶需要知道他們已經收到的部分是否有任何變化。但是,如果更改太多,我只是放棄并重新開始發送記錄。
uj5u.com熱心網友回復:
WITH max1000 AS (
SELECT the_row, count(*) OVER () AS total
FROM (
SELECT the_row -- named row type
FROM T AS the_row
WHERE updated_at > timestamp
AND name <= 'Michael'
ORDER BY name
LIMIT 1001
) sub
)
SELECT (the_row).* -- parentheses required
FROM max1000 m
WHERE total < 1001
UNION ALL
( -- parentheses required
SELECT *
FROM T
WHERE (SELECT total > 1000 FROM max1000 LIMIT 1)
ORDER BY name
LIMIT 25
)
subCTE 中的子查詢max1000獲取第一個查詢的完整排序結果 - 包裝為行型別,??并使用 withLIMIT 1001來避免多余的作業。
外部SELECT添加總行數。看:
- 使用 LIMIT/OFFSET 運行查詢并獲取總行數
第一個SELECT外部UNION查詢回傳分解的行作為結果 - 如果它們少于 1001。
SELECT外部查詢的第二個UNION回傳備用結果 - 如果超過 1000。括號是必需的 - 請參閱:
- 結合3個SELECT陳述句輸出1個表
或者:
WITH max1000 AS (
SELECT *
FROM T
WHERE updated_at > timestamp
AND name <= 'Michael'
ORDER BY name
LIMIT 1001
)
, ct(ok) AS (SELECT count(*) < 1001 FROM max1000)
SELECT *
FROM max1000 m
WHERE (SELECT ok FROM ct)
UNION ALL
( -- parentheses required
SELECT *
FROM T
WHERE (SELECT NOT ok FROM ct)
ORDER BY name
LIMIT 25
);
我覺得我更喜歡第二個。不確定哪個更快。
在大多數呼叫中,要么優化不到 1001 行的性能。如果那是例外,我會先運行一個更便宜的計數。還很大程度上取決于可用的索引...
如果第一個查詢未找到任何行,則您不會得到任何行。(似乎是一個奇怪的結果。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/480577.html
標籤:sql PostgreSQL 数数 限制
上一篇:在Postgres中選擇模式
下一篇:Windows10觸控鍵盤
