【问题标题】:Using multiple NOT IN in SQL Server在 SQL Server 中使用多个 NOT IN
【发布时间】:2018-03-28 12:28:36
【问题描述】:

我有两张这样的表:

表 1:City - 主键:ID_City

| City      | ID_City | ID_State|
+-----------+---------+---------+
| Chennai   | 1       | 2       |
| Bengaluru | 2       | 1       |
| Lucknow   | 3       | 3       |
|   .       | .       | .       |
|   .       | .       | .       |

我正在将新城市添加到现有数据库中,同时使用 NOT IN 检查现有城市。 @table 如下所示:

表一:@table

| City      | ID_State|Zip_Code|
+-----------+---------+--------+
| Chennai   | 2       |00001   |
| Chennai   | 2       |00002   |
| Chennai   | 2       |00003   |
| Bengaluru | 1       |10011   |
| Bengaluru | 1       |10012   |
| Bengaluru | 1       |10013   |
| Lucknow   | 3       |20001   |
| Mysore    | 4       |50001   |
| Mysore    | 4       |50002   |
| Mysore    | 4       |50003   |
|   .       | .       | .      |

预期结果:

  1. 查询应该检查已经存在的城市并过滤掉那些不应该添加的城市。 (这是使用 NOT IN 完成的)

  2. 另外,如果有多行相同城市,则不应添加相同城市的多个副本。例如:查询应该只添加一行 City- 'Mysore' 而不是三行

我执行的查询:

SELECT 
    City, id_state 
FROM 
    @table
WHERE 
    City NOT IN (SELECT City FROM City WHERE City IS NOT NULL)
    AND id_state NOT IN (SELECT id_state FROM City WHERE id_state IS NOT NULL)

【问题讨论】:

标签: sql sql-server notin


【解决方案1】:

一个城市名称可以属于多个州,因此您需要检查这两种组合。

我觉得下面的查询应该会给你想要的输出。

SELECT DISTINCT City, id_state 
FROM @table T1
WHERE NOT EXISTS
(
 SELECT 1 FROM City C WHERE C.City = T1.City AND T.id_state = C.id_state  
)

【讨论】:

    【解决方案2】:

    您可以使用 NOT IN 和 NOT EXISTS 来实现这一目标

    不在:

    SELECT DISTINCT t.City, t.id_state 
      FROM @table t 
     WHERE City NOT IN (SELECT c.City  FROM City WHERE c.city = t.city AND c.id_state = t.id_state)
    

    不存在:

    SELECT DISTINCT t.City, t.id_state 
      FROM @table t 
     WHERE NOT EXISTS  (SELECT TOP 1 c.city  FROM City WHERE c.city = t.city AND c.id_state = t.id_state)
    

    不存在比不存在更好。也不需要多个 NOT IN。

    【讨论】:

    • "NOT EXISTS 比 NOT IN 好"
    • 你能给我举个NOT IN更好的例子吗?这对我来说将是很好的学习。
    • 这种IN 子句(来自您的回答)有时比EXISTS 更快-我建议在给定情况下尝试两者并确定哪个更适合您:WHERE City NOT IN (SELECT c.City FROM City WHERE c.city = t.city AND c.id_state = t.id_state)跨度>
    【解决方案3】:

    您可以使用 select distinct:

    SELECT distinct City, id_state FROM @table WHERE City 
    NOT IN (SELECT City FROM City WHERE City IS NOT Null) AND id_state NOT 
    IN (SELECT id_state FROM City WHERE id_state IS NOT Null)
    

    【讨论】:

      【解决方案4】:

      考虑使用 NOT EXISTS 而不是 NOT IN:

      SELECT DISTINCT City
      ,               id_state
      FROM   @table t1
      WHERE  NOT EXISTS (   SELECT City
                            FROM   City t2
                            WHERE  t1.City = t2.City
                                   AND t1.id_state = t2.id_state 
                                   );
      

      原因:

      1. 一个子句中可以定义多个谓词,所以需要多个NOT IN
      2. 从性能角度来看,查询计划比 NOT IN 更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-04
        • 1970-01-01
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        相关资源
        最近更新 更多