SQL Server:对第一个查询中的空行集进行二次查询

SQL Server:对第一个查询中的空行集进行二次查询,sql,sql-server,Sql,Sql Server,假设我有下面的简单表格 表a { id int, pointId int, state int, 值int } 有以下两个问题: SELECT * FROM a WHERE state = 1 and pointId = x SELECT * FROM a WHERE state = 2 and pointId = x 是否有方法将这两个查询组合起来,以便: 如果查询1返回>0行,则返回查询1的结果 如果查询1返回0行,则返回查询2的结果 (因此,对于pointId=1,它将返回第1行,对

假设我有下面的简单表格

表a { id int, pointId int, state int, 值int }

有以下两个问题:

SELECT * FROM a WHERE state = 1 and pointId = x
SELECT * FROM a WHERE state = 2 and pointId = x
是否有方法将这两个查询组合起来,以便:

  • 如果查询1返回>0行,则返回查询1的结果
  • 如果查询1返回0行,则返回查询2的结果
(因此,对于pointId=1,它将返回第1行,对于pointId=3,它将返回第4行)

我一直在尝试将这两者结合在一起,做一些类似的事情

SELECT * FROM a WHERE state = 1 AND pointId = x
UNION ALL
SELECT * FROM a WHERE state = 2 AND pointId = x and 
pointId NOT IN (SELECT pointId FROM a WHERE state = 1 AND pointId = x)
我想知道我是不是在用这种方法来解决复杂的问题,还有没有更简单的方法。我意识到我可以运行第一个查询,然后在代码中处理它,但是如果我可以在sql中这样做,那就太好了。 任何建议或指点都很好

谢谢


一个

联合
用于组合元组,您的规范提到要返回一组元组或另一组元组。在这种情况下,您不想使用
联合
,您可以使用
存在

IF EXISTS(...insert your first query here...)
    BEGIN
       --a record exists process first query
    END
ELSE
    BEGIN
         --do other query
    END

对于您问题中的具体情况,您可以这样做

WITH T
     AS (SELECT *,
                DENSE_RANK() OVER (ORDER BY state) AS R
         FROM   a
         WHERE  state IN ( 1, 2 )
                AND pointId = x)
SELECT id,
       pointId,
       state,
       value
FROM   T
WHERE  R = 1; 
更一般地说,如果查询1可能很昂贵,您可以执行它,然后检查
@@ROWCOUNT
,以确定是否执行查询2


这意味着您的应用程序需要处理多个结果集。如果您不想处理第一个查询可以插入到表变量中的问题,那么您只需从中执行
选择
,如果
@@ROWCOUNT>0

,以下是维护和性能方面的最佳答案。 资料来源:


在这种情况下,你不应该使用UNION。您不希望合并记录-您希望根据
EXISTS
处理查询1或查询2。对:)但是,这将执行查询两次否?我示例中的表a实际上是一个巨大的表,我想知道是否有办法避免执行两次查询。。。(但已经非常感谢!)您没有处理或返回
EXISTS
子句。您正在检查记录是否存在。您还可以检查计数是否>0
从查询1
中选择计数(*),如果返回>0,则执行查询1,否则执行查询2。
WITH T
     AS (SELECT *,
                DENSE_RANK() OVER (ORDER BY state) AS R
         FROM   a
         WHERE  state IN ( 1, 2 )
                AND pointId = x)
SELECT id,
       pointId,
       state,
       value
FROM   T
WHERE  R = 1; 
WITH query1 AS (
    SELECT ...
),
query2 AS (
    SELECT ...
)
SELECT *
    FROM query1
UNION ALL
SELECT *
    FROM query2
    WHERE NOT EXISTS (
        SELECT NULL
        FROM query1
    );