我正在使用Postgresql DB。to_char where where子句SQL/Postgresql
我想對錶中的數字列執行查詢以查找值是否以特定數字開頭。
我目前有:
SELECT * FROM myTable WHERE to_char(ID, '12345678') LIKE '2%'
然而,這將返回一個空的數據集(但也有ID列與2
非常感謝
開始史蒂夫
我正在使用Postgresql DB。to_char where where子句SQL/Postgresql
我想對錶中的數字列執行查詢以查找值是否以特定數字開頭。
我目前有:
SELECT * FROM myTable WHERE to_char(ID, '12345678') LIKE '2%'
然而,這將返回一個空的數據集(但也有ID列與2
非常感謝
開始史蒂夫
不要笑。作爲替代鑄件,您可以使用範圍查詢,如:
SELECT * FROM mytable
WHERE id = 2
OR (id >=20 AND id < 30)
OR (id >=200 AND id < 300)
OR (id >=2000 AND id < 3000)
OR (id >=20000 AND id < 30000)
OR (id >=200000 AND id < 300000)
OR (id >=2000000 AND id < 3000000)
OR (id >=20000000 AND id < 30000000)
OR (id >=200000000 AND id < 300000000)
OR (id >=2000000000 AND id < 3000000000)
OR (id >=20000000000 AND id < 30000000000)
OR (id >=200000000000 AND id < 300000000000)
-- ...
;
這可能會導致Postgres而言,要產生一個更好的查詢計劃,因爲可以使用索引(如果存在的話,可以預期id字段)
UPDATE: 查詢計劃:
Bitmap Heap Scan on reservations (cost=1838.15..13290.11 rows=110809 width=4012) (actual time=11.310..24.379 rows=111111 loops=1)
Recheck Cond: ((id = 2) OR ((id >= 20) AND (id < 30)) OR ((id >= 200) AND (id < 300)) OR ((id >= 2000) AND (id < 3000)) OR ((id >= 20000) AND (id < 30000)) OR ((id >= 200000) AND (id < 300000)) OR ((id >= 2000000) AND (id < 3000000)) OR ((id >= 20000000) AND (id < 30000000)) OR ((id >= 200000000) AND (id < 300000000)) OR ((id >= 2000000000) AND (id < 3000000000::bigint)) OR ((id >= 20000000000::bigint) AND (id < 30000000000::bigint)) OR ((id >= 200000000000::bigint) AND (id < 300000000000::bigint)))
-> BitmapOr (cost=1838.15..1838.15 rows=112192 width=0) (actual time=11.242..11.242 rows=0 loops=1)
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.005..0.005 rows=1 loops=1)
Index Cond: (id = 2)
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.58 rows=10 width=0) (actual time=0.003..0.003 rows=10 loops=1)
Index Cond: ((id >= 20) AND (id < 30))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..2.52 rows=104 width=0) (actual time=0.013..0.013 rows=100 loops=1)
Index Cond: ((id >= 200) AND (id < 300))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..14.24 rows=1036 width=0) (actual time=0.110..0.110 rows=1000 loops=1)
Index Cond: ((id >= 2000) AND (id < 3000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..144.73 rows=10845 width=0) (actual time=1.050..1.050 rows=10000 loops=1)
Index Cond: ((id >= 20000) AND (id < 30000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1332.24 rows=100196 width=0) (actual time=10.013..10.013 rows=100000 loops=1)
Index Cond: ((id >= 200000) AND (id < 300000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.010..0.010 rows=0 loops=1)
Index Cond: ((id >= 2000000) AND (id < 3000000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)
Index Cond: ((id >= 20000000) AND (id < 30000000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)
Index Cond: ((id >= 200000000) AND (id < 300000000))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)
Index Cond: ((id >= 2000000000) AND (id < 3000000000::bigint))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.026..0.026 rows=0 loops=1)
Index Cond: ((id >= 20000000000::bigint) AND (id < 30000000000::bigint))
-> Bitmap Index Scan on reservations_pkey (cost=0.00..1.49 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)
Index Cond: ((id >= 200000000000::bigint) AND (id < 300000000000::bigint))
Total runtime: 28.720 ms
(28 rows)
Seq Scan on reservations (cost=0.00..19219.52 rows=4383 width=4012) (actual time=0.025..184.532 rows=111111 loops=1)
Filter: ((id)::text ~~ '2%'::text)
Total runtime: 189.100 ms
(3 rows)
值您不需要to_char
,只需要id like '2%'
。
呃,不。錯誤代碼0,SQL狀態42883:錯誤:運算符不存在:數字~~未知 提示:沒有運算符匹配給定的名稱和參數類型。您可能需要添加顯式類型轉換。 Position:42 – Steve
pl/sql抱歉;) – user1675905
@ user1675905可能值得刪除該答案。 –
我找到了答案:
SELECT * FROM myTable WHERE CAST (ID AS CHAR) LIKE '2%'
史蒂夫
小心;這會起作用,但可能並不完全是你認爲會的原因。不帶長度因子的CHAR將始終爲單個字符 - 通過運行「SELECT CAST(23456 as CHAR);'或類似的方法證明自己。您的答案中的語句在語義上與'SELECT * FROM myTable WHERE CAST(ID AS CHAR)='2''完全相同,因此如果您嘗試查找兩個字符的前綴,您會得到一個不愉快的驚喜。對「文本」的轉換可能不太令人驚訝。 – kgrittn
改爲將文字轉換爲文字。你也可以說文本(id)而不是cast(id爲文本)。此外,如果你這樣做,你會想索引輸出的文本(ID),以便您可以使用索引。 –
好點,謝謝 – Steve
這是因爲在TO_CHAR
爲一些圖案或者是9
或0
(帶前導零值)(與指定的位數的值)。請使用以下內容:
SELECT * FROM myTable WHERE TRIM(to_char(ID, '99999999')) LIKE '2%'
或將該數字轉換爲char。
這將返回前面的數字:
floor(a/10.^(floor(log(a))))
例子:
select a from generate_series(1,1000) as a where
floor(a/10.^(floor(log(a)))) = 2;
如果你有哪些是小於一或小於零的數字,您應該過濾出來(取決於你想要什麼)。
有用的是,這個表達式適用於函數索引,所以如果查詢運行得足夠頻繁或者足夠慢以便索引值得花費,那麼可以添加一個。 –
to_char的第二個參數用作模板。只有0和9適用於數字。你也可以使用簡單的轉換:'WHERE id :: text LIKE'2%'' – wildplasser