我有一个包含三列的表:“id”、“letter”和“number”。我有一个“字母”和“数字”对的列表,我需要在单个查询中获取“id”。显然,简单的解决方案是使用 n 个查询,其中 n 是列表的大小。
SELECT id FROM table WHERE number=... AND letter=...
Run Code Online (Sandbox Code Playgroud)
但这需要 n 个查询,在我的例子中是数百万个,并且开销很大。以前,我只有“数字”列表上的过滤器,所以我使用
SELECT id FROM table WHERE number = ANY(ARRAY[...])
Run Code Online (Sandbox Code Playgroud)
是否有一些语法可以满足我的需要,例如
SELECT id FROM table WHERE PAIR[letter,number] = ANY(ARRAY[PAIR[...],...])
Run Code Online (Sandbox Code Playgroud)
谢谢。
您可以使用行数组:
select id from table where (letter, number) = any(array[(l1, n1), (l2, n2), ...])
Run Code Online (Sandbox Code Playgroud)
如果您决定使用= any. 您可能需要包含大量类型转换以确保所有内容都对齐,因此它可能比加入 VALUES 列表更难看。
虽然您当然可以将 ARRAY 与<@(is-contained-by)运算符或ANY运算符一起使用,但您不需要为此使用数组。固定值上的AJOIN肯定会比其他选项运行得快得多。
考虑下test表的数据:
CREATE TEMP TABLE IF NOT EXISTS
test(id SERIAL, letter TEXT, num NUMERIC);
WITH letters AS (
SELECT chr(generate_series(65, 90)) AS letter
)
,numbers AS (
SELECT generate_series(101, 999) AS num
)
INSERT INTO test(letter, num)
SELECT letter, num
FROM letters, numbers
Run Code Online (Sandbox Code Playgroud)
您现在可以将值添加到查询中并执行JOIN. 例如,以下查询查找id('A', 105)、('B', 110) 和 ('C', 879) 对中的 :
SELECT id
FROM test T
JOIN (VALUES /* your query criteria goes here */
('A', 105)
,('B', 110)
,('C', 879)
) AS V(l, n)
ON T.letter = V.l AND T.num = V.n
Run Code Online (Sandbox Code Playgroud)
返回(假设之前没有对测试表进行写入):
id |
----|
5|
909|
2577|
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2758 次 |
| 最近记录: |