Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何为以下问题编写postgres查询?_Sql_Postgresql_Select - Fatal编程技术网

Sql 如何为以下问题编写postgres查询?

Sql 如何为以下问题编写postgres查询?,sql,postgresql,select,Sql,Postgresql,Select,我有四张桌子。一级,二级,三级,四级。每个都有键值对 我想得到一个键值对,这样如果键值对出现在level1中,那么它就不应该检查level2,3,4 如果在级别1中不存在,则应转到级别2;如果不存在,则转到级别3 值将始终出现在级别4中 因此,最终o/p为map类型 Level1 | Level2 | Level3 | Level4 key | value | key |value |

我有四张桌子。一级,二级,三级,四级。每个都有键值对

我想得到一个键值对,这样如果键值对出现在level1中,那么它就不应该检查level2,3,4

如果在级别1中不存在,则应转到级别2;如果不存在,则转到级别3

值将始终出现在级别4中

因此,最终o/p为map类型

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

sql查询是否可行,或者我是否需要为其编写函数或过程?

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

看到这个了吗


SQL是声明性的,所以很难在查询中产生副作用:如果您需要确切的行为,那么应该用过程语言实现它

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

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"
但是,仅根据需要访问表的副作用是不能保证的:SQL引擎可以在认为合适的时候自由访问表,只要使用UNION ALL即可

尽管直接的UNION在这里也可以工作

    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
给出:

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;

凉的让我试试。@user1298426我修复了查询。我在这里创建了一个SQLFIDLE:
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)