我有一个名为“where_clauses”的表,其中包含一系列我想用于构建动态查询的条件。我想知道我可以使用这些数据执行的所有可能的查询。这是我的“where_clauses”数据......
INSERT INTO where_clauses (id,col_name,clause) VALUES (1,'x','x < 1');
INSERT INTO where_clauses (id,col_name,clause) VALUES (2,'x','x < 2');
INSERT INTO where_clauses (id,col_name,clause) VALUES (3,'x','x < 3');
INSERT INTO where_clauses (id,col_name,clause) VALUES (4,'y','y < 1');
INSERT INTO where_clauses (id,col_name,clause) VALUES (5,'y','y < 2');
INSERT INTO where_clauses (id,col_name,clause) VALUES (6,'y','y < 3');
INSERT INTO where_clauses (id,col_name,clause) VALUES (7,'z','z < 1');
理想情况下,我希望以一系列ID形式提供“所有可能的查询”。例如,“所有可能的查询”结果将是......
{1}
{1,4}
{1,4,7}
{1,5}
{1,5,7}
{1,6}
{1,6,7}
{2}
{2,4}
{2,4,7}
{2,5}
{2,5,7}
{2,6}
{2,6,7}
{3}
{3,4}
{3,4,7}
{3,5}
{3,5,7}
{3,6}
{3,6,7}
{4}
{4,7}
{5}
{5,7}
{6}
{6,7}
{7}
请注意,即时抛出加入相等的列。什么是可以提供所有可能的where_clauses的查询?
答案 0 :(得分:1)
这是new WITH RECURSIVE
旨在解决的问题。以下内容适用于任意数量的列名称(不只是x
,y
,z
)。
WITH RECURSIVE subq(a, x) AS
( VALUES (ARRAY[]::int[], NULL) /* initial */
UNION ALL
SELECT subq.a || id, col_name FROM subq JOIN where_clauses
ON x IS NULL OR x < col_name )
SELECT a FROM subq
WHERE x IS NOT NULL; /* discard the initial empty array */
答案 1 :(得分:0)
尝试此代码,它选择三列,那些未用于子句的列保留为NULL,您可以进一步连接或操作该结果:
--all possibilities with only one clause
SELECT
id AS ID1, NULL ID2, NULL AS ID3
FROM where_clauses
--all possibilities with two clauses (xy,xz,yz)
UNION
SELECT
WC1.id AS ID1, WC2.id AS ID2, NULL AS ID3
FROM where_clauses WC1
CROSS JOIN where_clauses WC2
WHERE
WC1.col_name != WC2.col_name
AND WC1.id > WC2.id
--all possibilities with an x and a y and a z clause
UNION
SELECT
WC1.id AS ID1, WC2.id AS ID2, WC3.id AS ID3
FROM where_clauses WC1
CROSS JOIN where_clauses WC2
CROSS JOIN where_clauses WC3
WHERE
WC1.col_name != WC2.col_name
AND WC1.id > WC2.id
AND WC1.col_name != WC3.col_name
AND WC1.id > WC3.id
AND WC2.col_name != WC3.col_name
AND WC2.id > WC3.id
Here是一个小提琴。
编辑:略微修饰小提琴
答案 2 :(得分:0)
SELECT string_to_array(TRIM(x || ',' || y || ',' || z, ','), ',')
FROM (
WITH sq AS (
SELECT a.id x, b.id y, c.id z
FROM where_clauses a, where_clauses b, where_clauses c
WHERE a.col_name != b.col_name AND
a.col_name != c.col_name AND
b.col_name != c.col_name AND
a.id < b.id AND
b.id < c.id
)
SELECT x, y, z FROM sq
UNION ALL
SELECT distinct x, y, null::int FROM sq
UNION ALL
SELECT distinct y, z, null::int FROM sq
UNION ALL
SELECT distinct x, null::int, null::int FROM sq
UNION ALL
SELECT distinct y, null::int, null::int FROM sq
UNION ALL
SELECT distinct z, null::int, null::int FROM sq
) ORDER BY 1;
以上查询可以帮助您吗?