【问题标题】:TSQL to get missing records inside IN operatorTSQL 在 IN 运算符中获取丢失的记录
【发布时间】:2020-09-16 10:06:49
【问题描述】:

我在 SQL Server 中有一个如下表:

create table address (id int, city varchar(10));

insert into address values (1, 'Rome');
insert into address values (2, 'Dallas');
insert into address values (3, 'Cracow');
insert into address values (4, 'Moscow');
insert into address values (5, 'Liverpool');
insert into address values (6, 'Cracow');
insert into address values (7, 'Seoul');

我正在使用IN 运算符编写查询

SELECT City 
FROM address 
WHERE city IN ('Rome', 'Mumbai', 'Dallas', 'Delhi', 'Moscow')

我可以得到结果,但我想获取表格中缺失或不可用记录的列表,如

|  City  |  Status   |
+--------+-----------+
| Rome   | Available |
| Dallas | Available |
| Moscow | Available |
| Mumbai | Missing   |
| Delhi  | Missing   |
+--------+-----------+

【问题讨论】:

    标签: sql sql-server tsql select sql-in


    【解决方案1】:

    为此,我建议使用行构造函数values() 而不是in

    select c.city, case when a.city is null then 'Missing' else 'Available' end status
    from values(('Rome'), ('Mumbai'), ('Dallas'), ('Delhi'), ('Moscow')) c(city)
    left join address a on a.city = c.city
    

    如果address 表中有重复的city,那么exists 是更好的选择:

    select 
        c.city, 
        case when exists(select 1 from address a where a.city = c.city)
            then 'Available'
            else 'Missing' 
    end status
    from values(('Rome'), ('Mumbai'), ('Dallas'), ('Delhi'), ('Moscow')) c(city)
    

    【讨论】:

      【解决方案2】:

      使用使用VALUES 的派生表来表示所有相关城市,并使用CASE 表达式和EXISTS 来检查是否存在带有城市的地址。

      SELECT city.name city,
             CASE
               WHEN EXISTS (SELECT *
                                   FROM address
                                   WHERE address.city = city.name) THEN
                 'Available'
               ELSE
                 'Missing'
             END status
             FROM (VALUES ('Rome'),
                          ('Mumbai'),
                          ('Dallas'),
                          ('Delhi'),
                          ('Moscow')) city (name);
      

      db<>fiddle

      【讨论】:

        【解决方案3】:

        你可以使用 IIF

        SELECT [City], 
           IIF([City] IN('Rome', 'Mumbai', 'Dallas', 'Delhi', 'Moscow'), 'Available', 'Missing') STATUS
        FROM [Address];
        

        Result

        【讨论】:

          【解决方案4】:

          使用 CTE:

          with CitySearch (city) as (
          select 'Rome' union all
          select 'Mumbai'  union all
          select 'Dallas'  union all
          select 'Delhi'  union all
          select 'Moscow' 
          )
          select t1.city,
          case when t2.city is null then 'Missing' else 'Available' end Status
          from CitySearch t1
          left outer join address t2 on t1.city=t2.city
          order by 2
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多