TSQL 在 IN 运算符中获取丢失的记录

Posted

技术标签:

【中文标题】TSQL 在 IN 运算符中获取丢失的记录【英文标题】:TSQL to get missing records inside IN operator 【发布时间】: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   |
+--------+-----------+

【问题讨论】:

【参考方案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

【讨论】:

以上是关于TSQL 在 IN 运算符中获取丢失的记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 IN 运算符进行 BigTable 查询以获取所有用户组键

TSQL - 对象或列名丢失或为空.. 尝试将 sql server 数据库备份到磁盘时

IN 运算符不返回范围内的所有记录

如何使用 TSQL 而不是 linq 获取和跳过记录 [重复]

在 Amazon Redshift 中,虽然我已将 service_date 列指定为 Date 数据类型,但是当我在 IN 运算符中获取日期时,它仅使用引号

JS位运算异常(位运算精度丢失)的原因探究