查询子查询的所有记录不存在的位置

时间:2017-05-09 15:31:33

标签: sql

我有两个表结构和插入如下

产品:

productno   Products    State
    1001      a         liquid
    1002      b         liquid
    1003      c         liquid
    1004      d         Solid
    1005      e         Solid
    1006      f         Solid

订单:

orderno Productno
101 1001
101 1003
101 1002
102 1001
102 1004
102 1005
102 1006
103 1006
104 1002
105 1004
106 1001
106 1002
106 1003
106 1006

并插入陈述

CREATE TABLE product (productno NUMBER,product VARCHAR2(10),states VARCHAR2(15));
INSERT INTO product (productno,product,states) VALUES (1001,'a','liquid');
INSERT INTO product (productno,product,states) VALUES (1002,'b','liquid');
INSERT INTO product (productno,product,states) VALUES (1003,'c','liquid');
INSERT INTO product (productno,product,states) VALUES (1004,'d','Solid');
INSERT INTO product (productno,product,states) VALUES (1005,'e','Solid');
INSERT INTO product (productno,product,states) VALUES (1006,'f','Solid');

CREATE TABLE orders (ordersno NUMBER,productno NUMBER);
INSERT INTO orders (ordersno,productno) VALUES (101,1001);
INSERT INTO orders (ordersno,productno) VALUES (101,1003);
INSERT INTO orders (ordersno,productno) VALUES (101,1002);
INSERT INTO orders (ordersno,productno) VALUES (102,1001);
INSERT INTO orders (ordersno,productno) VALUES (102,1004);
INSERT INTO orders (ordersno,productno) VALUES (102,1005);
INSERT INTO orders (ordersno,productno) VALUES (102,1006);
INSERT INTO orders (ordersno,productno) VALUES (103,1006);
INSERT INTO orders (ordersno,productno) VALUES (104,1002);
INSERT INTO orders (ordersno,productno) VALUES (105,1004);
INSERT INTO orders (ordersno,productno) VALUES (106,1001);
INSERT INTO orders (ordersno,productno) VALUES (106,1002);
INSERT INTO orders (ordersno,productno) VALUES (106,1003);
INSERT INTO orders (ordersno,productno) VALUES (106,1006);

我想构建一个查询来列出没有所有Liquid产品的订单。

例如

1)orderno 101&因为所有3种液体产品(1001,1002,1003)都存在,所以106不应该输出。

2)orderno 102应该在输出中,因为只有一种液体产品(1001)存在。与orderno 104相同

3)orderno 103& 105应该在那里作为非液体产品的输出。

3 个答案:

答案 0 :(得分:0)

一种方法是使用聚合。以下内容返回具有液体或固体产品的订单,但不是全部产品:

select o.ordersno, p.state
from products p join
     orders o
     on p.productno = o.productno
group by o.ordersno, p.state
having count(distinct o.productno) < (select count(p2.productno)
                                      from products p2
                                      where p2.state = p.state
                                     );

答案 1 :(得分:0)

在PostgreSQL中:

SELECT o.ordersno
FROM orders o JOIN product p ON o.productno = p.productno
GROUP BY o.ordersno
HAVING string_agg(distinct p.states, '') <> 'liquid';

如果您使用其他数据库,请搜索varchar的AGGREGATE FUNCTION。所有数据库都有varchar的聚合函数。

答案 2 :(得分:0)

选择所有产品状态不是 liquid ,并通过产品标识符将其加入订单。要排除重复的行,请使用DISTINCT修饰符。

SELECT DISTINCT
    orderno
FROM
    Orders 
JOIN
    (SELECT *
    FROM
        Products
    WHERE
        NOT State = 'liquid'
    ) ON Orders.Productno = Products.productno;