Select 用于组合的 postgresql
Select postgresql for combinations
我有以下 2 个 table:
SQL Tables
我有一个 ID 列表 (1,2,3,4,5,6,7,8, ..., 10000)。
这些 id 的唯一组合被插入到另一个 table.
那么,如果我将 id 列表传递给搜索,我如何才能找到这些独特的组合。
例如,我搜索 ARRAY([2,3,4])
。只有unique_combnation1的组合才存在,所以结果如下:
1 3
1 2
1 4
没有任何 unique_comb 包含 ids ARRAY([2,3,4])。
如果我搜索[1,4],结果如下:
1 3
1 2
1 4
2 2
2 4
2 5
我该怎么做?我知道如何以糟糕的方式做到这一点:
- 创建临时 TABLE t1
- 遍历给定的 ID:
SELECT * FROM .. where id = ANY(ARRAY[1,4])
并获取所有行,将所有行插入到 t1 中。
- 然后按 unique_comb.
对所有内容进行分组
- 然后统计组数。如果唯一组合的数量不超过1,则return唯一组合的id,否则(唯一组合> 1)return无
是否可以用 1-2 sql 行制作它?我正在使用 postgresql 9.3
select unique_comb t2 where id = ANY(ARRAY[1, 4]) group by unique_comb ...
下面的答案是正确的。我只修改了一点查询,它就开始工作了。
它会从table个独特的东西中选择几个id。
select unique_comb, array_agg(id) t2 where id = ANY(ARRAY[1, 4]) group by unique_comb
的结果如下:
您描述的过程似乎类似于 group by
:
select unique_comb
from t2
where id = ANY(ARRAY[1, 4])
group by unique_comb
having count(*) = array_length(ARRAY[1, 4], 1);
对于big表,以及long 数组(不适用于只有 2 或 3 个元素的示例),使用递归 CTE 的更复杂的查询会更快。
在任何情况下,您都需要 (id, unique_comb)
上的索引 - 按此顺序!主键很好用。
WITH RECURSIVE cte AS (
SELECT unique_comb, id, 2 AS i -- start with index for 2nd array elem
FROM tbl
WHERE id = 5 -- *first* element array
UNION ALL
SELECT t.unique_comb, t.id, c.i + 1
FROM cte c
JOIN tbl t USING (unique_comb)
WHERE t.id = ('{5, ... long array ... , 4}'::int[])[c.i] -- your array here
)
SELECT unique_comb
FROM cte
WHERE id = 4; -- *last* element of array
这种方法的优点是在游戏早期就排除了大部分(或所有)行。如果你有关于价值频率的信息,你会把最稀有的元素放在第一位。
我有以下 2 个 table: SQL Tables
我有一个 ID 列表 (1,2,3,4,5,6,7,8, ..., 10000)。 这些 id 的唯一组合被插入到另一个 table.
那么,如果我将 id 列表传递给搜索,我如何才能找到这些独特的组合。
例如,我搜索 ARRAY([2,3,4])
。只有unique_combnation1的组合才存在,所以结果如下:
1 3
1 2
1 4
没有任何 unique_comb 包含 ids ARRAY([2,3,4])。
如果我搜索[1,4],结果如下:
1 3
1 2
1 4
2 2
2 4
2 5
我该怎么做?我知道如何以糟糕的方式做到这一点:
- 创建临时 TABLE t1
- 遍历给定的 ID:
SELECT * FROM .. where id = ANY(ARRAY[1,4])
并获取所有行,将所有行插入到 t1 中。 - 然后按 unique_comb. 对所有内容进行分组
- 然后统计组数。如果唯一组合的数量不超过1,则return唯一组合的id,否则(唯一组合> 1)return无
是否可以用 1-2 sql 行制作它?我正在使用 postgresql 9.3
select unique_comb t2 where id = ANY(ARRAY[1, 4]) group by unique_comb ...
下面的答案是正确的。我只修改了一点查询,它就开始工作了。
它会从table个独特的东西中选择几个id。
select unique_comb, array_agg(id) t2 where id = ANY(ARRAY[1, 4]) group by unique_comb
的结果如下:
您描述的过程似乎类似于 group by
:
select unique_comb
from t2
where id = ANY(ARRAY[1, 4])
group by unique_comb
having count(*) = array_length(ARRAY[1, 4], 1);
对于big表,以及long 数组(不适用于只有 2 或 3 个元素的示例),使用递归 CTE 的更复杂的查询会更快。
在任何情况下,您都需要 (id, unique_comb)
上的索引 - 按此顺序!主键很好用。
WITH RECURSIVE cte AS (
SELECT unique_comb, id, 2 AS i -- start with index for 2nd array elem
FROM tbl
WHERE id = 5 -- *first* element array
UNION ALL
SELECT t.unique_comb, t.id, c.i + 1
FROM cte c
JOIN tbl t USING (unique_comb)
WHERE t.id = ('{5, ... long array ... , 4}'::int[])[c.i] -- your array here
)
SELECT unique_comb
FROM cte
WHERE id = 4; -- *last* element of array
这种方法的优点是在游戏早期就排除了大部分(或所有)行。如果你有关于价值频率的信息,你会把最稀有的元素放在第一位。