首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在同一列上使用In和Not In子句的SQL查询

在同一列上使用In和Not In子句的SQL查询
EN

Stack Overflow用户
提问于 2013-03-27 19:14:01
回答 5查看 11.4K关注 0票数 1
代码语言:javascript
复制
Product Name    Product Id  Product Status
A               1           Rollout
A               1           Storage
A               1           Delivered
A               5           Storage
B               2           Rollout
C               3           Rollout
A               4           Rollout
A               5           Rollout
B               6           Rollout
C               7           Rollout

在上面的表格中,我想写下下面的查询,它应该返回如下结果

代码语言:javascript
复制
Product Name QOH
A            1
B            0
C            0

查询:

代码语言:javascript
复制
SELECT Product Name, Count(Product Id) 
FROM table_t1 
WHERE Product Status IN ('Storage') AND Product Status NOT IN ('Delivered')

但是上面的查询返回以下结果

代码语言:javascript
复制
Product Name QOH
A            2
B            0
C            0

请帮帮忙。

EN

回答 5

Stack Overflow用户

发布于 2013-03-27 19:36:40

您应该能够使用以下查询:

代码语言:javascript
复制
select distinct t.[product name], 
  coalesce(p.QOH, 0) QOH
from yourtable t
left join
(
  select t1.[product name], count(*) QOH
  from yourtable t1
  where [Product Status] = 'Storage'
    and not exists (select [product id]
                    from yourtable t2
                    where [Product Status] = 'Delivered'
                      and t1.[product id] = t2.[product id])
  group by t1.[product name]
) p
  on t.[product name] = p.[product name]

请参阅SQL Fiddle with Demo

原始查询的问题是一个产品不能同时有两个状态。您试图返回同时具有StorageDelivered状态的行,而这在逻辑上是不可能的。

我使用了一个子查询,它返回状态为Storage的行,但是product id在表中没有状态为Delivered的另一行(这是where子句中的not exists )。

有了这些结果后,您必须连接回您的表以返回所有不同的产品。

下面的查询给出了结果:

代码语言:javascript
复制
| PRODUCT NAME | QOH |
----------------------
|            A |   1 |
|            B |   0 |
|            C |   0 |
票数 2
EN

Stack Overflow用户

发布于 2021-05-01 22:14:01

我不完全同意这样的说法,即这是不合逻辑的。同一列上的IN和NOT IN子句是合法且合乎逻辑的。这就像做Set Minus (Set A - Set B)一样。

话虽如此,上面的例子

代码语言:javascript
复制
SELECT Product Name, Count(Product Id) 
FROM table_t1 
WHERE Product Status IN ('Storage') AND Product Status NOT IN ('Delivered')

完全相同于

代码语言:javascript
复制
SELECT Product Name, Count(Product Id) 
FROM table_t1 
WHERE Product Status IN ('Storage')

因此结果就是。在这个例子中不是很有用。但在某些情况下,将IN和NOT IN放在一起使用是很有用的,即使在同一列上也是如此。

例如,我有一个很长的项目白名单,我想要包含在IN中,同时,我想过滤掉现有黑名单中的一些项目。当然,我们可以先做Set - do,然后让查询做IN (Result of whitelist - blacklist)。但我们也可以做IN (whitelist) AND NOT IN (blacklist)

票数 1
EN

Stack Overflow用户

发布于 2013-03-27 19:19:00

您在开始时是按Product Status筛选表,因此您不会以这种方式看到B和C。您需要使用分组:

代码语言:javascript
复制
Select 
    [Product Name]
    ,QOH = sum(case when [Product Status]='Storage' then 1 else 0 end)
group by 
    [Product Name]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15657485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档