SQL选择不包括某些状态的记录

时间:2013-07-02 20:00:11

标签: sql select

我完全坚持如何创建这个选择。我需要从状态表中选择那些没有状态2的order_id

这是表格:

+----+---------+---------+--
| id | order_id| status  |
+----+---------+---------+--
|  1 |       1 |       1 | 
|  2 |       1 |       2 | 
|  3 |       2 |       1 | 
|  4 |       2 |       2 |
|  5 |       3 |       1 |
|  1 |       3 |       3 | 
|  2 |       4 |       2 | 
|  3 |       4 |       1 | 
|  4 |       4 |       2 |
|  5 |       5 |       3 | 
+----+---------+----------+--

所以他选择的结果只有order_id = 5

请帮忙!

如果您想要包含状态为1的订单并排除状态为3的订单,那么您可以使用类似的想法:

having sum(case when status_id = 1 then 1 else 0 end) > 0 and
       sum(case when status_id = 3 then 1 else 0 end) = 0

编辑:我喜欢排除那些order_id的:
  - 只有状态1(不是状态2)
  - 和
  - 状态为3

让我们有这样的表:

id--order-id-Prod---Status    
------------------------------  

1   1        a      1  
6   1        b      2  
7   1        a      2  
8   1        b      1  
9   2        a      1  
10  3        a      1  
11  3        b      1  
12  3        a      2  
13  3        b      2  
14  4        a      1  
15  4        b      1  
16  5        a      1  
17  5        b      1  
18  5        a      2  
19  5        b      2  
20  5        a      3  
21  5        b      3  

选择应仅显示order_id“5”

4 个答案:

答案 0 :(得分:4)

这是set-within-sets查询的示例:

select order_id
from t
group by order_id
having sum(case when status = 2 then 1 else 0 end) = 0

having子句计算状态为2的行数。= 0查找没有匹配的订单。

编辑:

如果您想要包含状态为1的订单并排除状态为3的订单,那么您可以使用类似的想法:

having sum(case when status_id = 1 then 1 else 0 end) > 0 and
       sum(case when status_id = 3 then 1 else 0 end) = 0

答案 1 :(得分:3)

这是一种方式。

Select * from TableName 
where Order_ID not in (Select order_ID from tableName where status=2)

另一种方法是使用not exists子句。

答案 2 :(得分:1)

另一种方法是使用EXCEPT

SELECT order_id
FROM StatusTable

EXCEPT

SELECT order_id
FROM StatusTable
WHERE status = 2;

它适用于SQL-Server和Postgres(如果用EXCEPT替换MINUS,则适用于Oracle。)

答案 3 :(得分:0)

我认为这是有效的,一个用于选择所有ID的查询,一个用于获取状态为2的用户并在order_id上保持连接,并在状态为2的订单列表中选择null order_id。

select 
  all_ids.order_id
from 
(
  select distinct
    order_id
  from status
) all_ids
left join
(
  select 
    order_id
  from status
  where status = 2
) two_ids
on all_ids.order_id = two_ids.order_id
where two_ids.order_id is null