2

我有一个名为“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 的查询?

4

3 回答 3

1

这是 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 */
于 2013-04-11T08:10:03.180 回答
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

是一个小提琴。

编辑:稍微修改小提琴

于 2013-04-11T07:46:03.963 回答
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;

以上查询对您有帮助吗?

于 2013-04-11T07:57:59.053 回答