Postgresql合并模拟查询联合

时间:2018-03-03 00:40:57

标签: sql postgresql union coalesce

我有这样的查询

select house, street, town, 10 as weight 
from addresses
where 
    house match query,
    street match query,
    city match query
union all 
select house, street, town, 5
    from addresses
where 
    street match query,
    city match query

我希望第二个查询仅在第一个查询为空时执行。我知道我可以添加where子句并检查先前查询的结果,但是如果我添加3或4个可选的子查询,那就会变得太笨重。

我知道它可以用plpgsql,但是可能已经测试过标准函数或语法了吗?

2 个答案:

答案 0 :(得分:1)

联合在一起的查询的一个有意识的特征是它们不能相互引用。你最好的选择就是把更多的sql包装成你所拥有的。

一个选项可能是添加另一列(可能称为source_id,然后使用窗口函数查找最低source_id,然后使用该列进行过滤。

http://sqlfiddle.com/#!17/c1004/1

WITH
  source_data AS
(
  SELECT 1 as source_id, * FROM test WHERE x > 10
  UNION ALL
  SELECT 2 as source_id, * FROM test WHERE x < 10
  UNION ALL
  SELECT 3 as source_id, * FROM test WHERE x = 10
),
  source_scanned AS
(
  SELECT
    MIN(source_id) OVER () AS min_source_id,
    *
  FROM
    source_data
)
SELECT
  *
FROM
  source_scanned
WHERE
  source_id = min_source_id

然而,这意味着执行所有查询并在所有结果的顶部运行一些处理。就个人而言,我使用plpgsql (将结果插入到临时表中,迭代查询,直到实际插入任何行)

答案 1 :(得分:0)

你可以做一个条件联盟:

with main as (
  select house, street, town, 10 as weight 
  from addresses
  where ...
)
select *
from main
union all 
select *
from addresses
where ...
 and not exists (select *
                 from main
                 limit 1);

子选择中的LIMIT 1可能不是必需的,因为Postgres查询刨器足够智能,但它也不会受伤。