如何为下面的问题编写postgres查询?

时间:2014-04-25 09:05:07

标签: sql postgresql select

      Level1         |    Level2      |     Level3          |     Level4
key       |  value   | key     |value |    key     | value  |  key     | value
---------------------|----------------|---------------------|-----------------  
setting1  |  true    |                |  setting1  |  true  |setting1  | false
                     |setting2 | false|                     |setting2  | false    
                     |                |                     |setting3  | true

我有4张桌子。 Level1,Level2,Level3,Level4。每个都有键值对。

我想得到键值对,这样如果在level1中存在键值对,则它不应该检查level2,3,4。

如果它在level1中不存在,那么它应该转到level2,如果不是level3。

值将始终存在于level4中。

所以最终的o / p是类型map。

key       |  value
---------------------
setting1  |  true
setting2  |  false
setting3  |  true

是否可以使用sql查询或者是否需要为其编写函数或过程?

3 个答案:

答案 0 :(得分:1)

SQL是声明性的,因此很难在查询中执行副作用:如果您需要完全行为,则应使用过程语言实现它。

如果您关心的是查询功能等同于您所描述的内容,则可以使用以下查询:

    select key, value from (
        select 1 as precedence, key, value from t1
        union all
        select 2 as precedence, key, value from t2
        union all
        select 3 as precedence, key, value from t3
        union all
        select 4 as precedence, key, value from t4
    )
    where key = <searched key>
    order by precedence asc
    limit 1

但是,不能保证只根据需要访问表的副作用:只要SQL引擎认为适当,就可以自由访问表

答案 1 :(得分:1)

你希望{UN了所有人DISTINCT ON(虽然一个直的UNION也可以在这里工作)

BEGIN;

CREATE TEMP TABLE settings1 (key text, value text, PRIMARY KEY (key));
CREATE TEMP TABLE settings2 (key text, value text, PRIMARY KEY (key));
CREATE TEMP TABLE settings3 (key text, value text, PRIMARY KEY (key));

INSERT INTO settings1 VALUES ('a', 'a1');
INSERT INTO settings2 VALUES ('a', 'a2');
INSERT INTO settings2 VALUES ('b', 'b2');
INSERT INTO settings3 VALUES ('b', 'b3');
INSERT INTO settings3 VALUES ('c', 'c3');

SELECT DISTINCT ON (key) key, value FROM (
    SELECT 1 AS lvl, key, value FROM settings1
    UNION ALL
    SELECT 2 AS lvl, key, value FROM settings2
    UNION ALL
    SELECT 3 AS lvl, key, value FROM settings3
    ORDER BY key, lvl
) AS settings;

ROLLBACK;

给出:

 key | value 
-----+-------
 a   | a1
 b   | b2
 c   | c3
(3 rows)

答案 2 :(得分:0)

一种方法是使用CASE - WHEN结构。

请参阅此SQLFiddle

SELECT CASE WHEN t1."key" IS NOT NULL
            THEN t1."key"
            ELSE CASE WHEN t2."key" IS NOT NULL
                      THEN t2."key"
                      ELSE CASE WHEN t3."key" IS NOT NULL
                                THEN t3."key"
                                ELSE t4."key"
                           END
                 END
       END
       as "key",
       CASE WHEN t1."value" IS NOT NULL
            THEN t1."value"
            ELSE CASE WHEN t2."value" IS NOT NULL
                      THEN t2."value"
                      ELSE CASE WHEN t3."value" IS NOT NULL
                                THEN t3."value"
                                ELSE t4."value"
                           END
                 END
       END
       as "value"
FROM table4 t4
LEFT JOIN table1 t1 ON t4."key" = t1."key"
LEFT JOIN table2 t2 ON t4."key" = t2."key"
LEFT JOIN table3 t3 ON t4."key" = t3."key"