sql - 合并两个 SQL 查询

标签 sql postgresql select coalesce isnull

我需要一个模仿以下形式的 if-then-else 语句的 SQL 查询:

if (query1 != null)
  return query1
else
  return query2

由于 COALESCE 不适用于结果集,因此我创建了一个联合查询来完成这项工作:

SELECT * FROM obs WHERE cond1  --query1
UNION
SELECT * FROM obs WHERE (NOT EXISTS(query1)) AND cond2

在 SQL 中:

  ( SELECT * FROM obs WHERE src = @id AND tstart <= @instant AND tend >= @instant )
  UNION
  ( SELECT * FROM obs WHERE (NOT EXISTS (SELECT 1 FROM obs WHERE src = @id AND tstart <= @instant AND tend >= @instant )) AND src = @id AND tstart <= @instant ORDER BY tend DESC LIMIT 1);

表 obs 具有字段 ( src | tstart | tent | ... )。我想选择与@instant 重叠的那些行。如果没有找到重叠行,则应返回 @instant 之前最接近的行。

SQL UNION 语句可以工作,但它非常笨拙,我正在寻找更短、更清晰的语句。具有 COALESCE ( query1, query2 ) 精神的东西会很好。我的数据库是Postgresql。

最佳答案

首先,在这种情况下,union all 可能比 union 更合适。

其次,您可以使用 with 来表达这一点以简化查询:

WITH t1 as (
      SELECT *
      FROM obs
      WHERE src = @id AND tstart <= @instant AND tend >= @instant
     )
SELECT t1.*
FROM t1
UNION ALL
(SELECT *
 FROM obs
 WHERE NOT EXISTS (SELECT 1 FROM t1) AND
       src = @id AND tstart <= @instant
 ORDER BY tend DESC
 LIMIT 1
);

但是,如果您正在查找单行,这会更简单:

 SELECT *
 FROM obs
 WHERE src = @id
 ORDER BY (CASE WHEN  tstart <= @instant AND tend >= @instant THEN 1
                ELSE 2
           END),
          tend DESC
 LIMIT 1;

而且,如果不是单行,也可以使用窗口函数:

SELECT o.*
FROM (SELECT o.*,
             DENSE_RANK() OVER (PARTITION BY src
                                ORDER BY (CASE WHEN tstart <= @instant AND tend >= @instant THEN 1
                                               ELSE 2
                                          END),
                                         (CASE WHEN tstart <= @instant AND tend >= @instant THEN NULL
                                               ELSE tend
                                          END) DESC
                               ) as seqnum
      FROM obs o
      WHERE src = @id
     ) o
WHERE seqnum = 1;

关于sql - 合并两个 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35409591/

相关文章:

sql - DB2 查询 - 消除最大值

Mysql如何获取每个月的注册用户总数

java - 与编码相关的数据库连接错误

python - Pandas 或 SQL 中异常的表缩减

select - 使用 select、epoll 或 kqueue 服务大文件

php - 是否可以在加载时发送 AJAX 请求?

sql - Oracle 中的物化 View 与临时表

mysql - 计数连接中的重复列名

ruby-on-rails - 即使字符串输入小于4,“对于字符变化(4)来说值太长”

php - MySQL只选择特定行