2

是否可以将 的值EXISTS用作查询的一部分?

请注意:不幸的是,由于客户端的限制,我需要 SQLServer 2005 兼容的答案!)

因此,当返回一组结果时,其中一个列是一个布尔值,它说明子查询是否会返回任何行。

例如,我想返回用户名列表以及不同的表是否包含每个用户的任何行。以下在语法上不正确,但希望能让您了解我的意思......

SELECT T1.[UserName],
    (EXISTS (SELECT * 
             FROM [AnotherTable] T2 
             WHERE T1.[UserName] = T2.[UserName])
    ) AS [RowsExist]
FROM [UserTable] T1

结果集包含一个名为的列和一个名为的[UserName]布尔列[RowsExist]

显而易见的解决方案是使用 a CASE,如下所示,但我想知道是否有更好的方法......

SELECT T1.[UserName],
    (CASE (SELECT COUNT(*)
           FROM [AnotherTable] T2 
           WHERE T1.[UserName] = T2.[UserName]
          )
          WHEN 0 THEN CAST(0 AS BIT)
          ELSE CAST(1 AS BIT) END
    ) AS [RowsExist]
FROM [UserTable] T1
4

3 回答 3

2

您的第二个查询不是有效的语法。

SELECT T1.[UserName],
       CASE
         WHEN EXISTS (SELECT *
                      FROM   [AnotherTable] T2
                      WHERE  T1.[UserName] = T2.[UserName]) THEN CAST(1 AS BIT)
         ELSE CAST(0 AS BIT)
       END AS [RowsExist]
FROM   [UserTable] T1 

一般没问题,将作为半连接实现。

CASE 表达式中的子查询一文进一步讨论了这一点。

在某些情况下,COUNT查询实际上可以执行得更好,尽管如此处所讨论

于 2013-09-13T13:44:56.910 回答
1

根据您在此处写的内容,我会将您的第一个查询更改为类似的内容

SELECT
        T1.[UserName], ISNULL(
            (
                SELECT
                        TOP 1 1
                    FROM [AnotherTable]
                    WHERE EXISTS
                        (
                            SELECT
                                    1
                                FROM [AnotherTable] AS T2
                                WHERE T1.[UserName] = T2.[UserName]
                        )
            ), 0)
    FROM [UserTable] T1

但实际上如果你用TOP 1 1你就不需要了EXISTS,你也可以写

SELECT
        T1.[UserName], ISNULL(
            (
                SELECT
                        TOP 1 1
                    FROM [AnotherTable] AS T2
                    WHERE T1.[UserName] = T2.[UserName]
            ), 0)
    FROM [UserTable] T1
于 2013-09-13T13:43:35.013 回答
1

我更喜欢其他人的 sql 但我只是写了这个:

with bla as (
    select t2.username, isPresent=CAST(1 AS BIT)
    from t2
    group by t2.username
)
select t1.*, isPresent = isnull(bla.isPresent, CAST(0 AS BIT))
from t1 
    left join blah on t1.username=blah.username
于 2013-09-13T13:48:48.977 回答