MySQL独占行选择

时间:2012-06-23 14:35:28

标签: mysql

我有一个名为'survey_product'的表,其结构如下:

id int(11)
order_id int(11)
product_id int(11)
pq1 varchar(2)
pq2 varchar(2)
pq3 varchar(2)

此表存储通过系统订购的产品。

以下是该表中的一些数据记录:

(1, 2, 20, '1', '1', 'y')
(2, 2, 21, '1', 'y', 'y')
(3, 2, 22, '1', 'y', 'n')
(4, 2, 23, '1', 'y', 'y')
(5, 2, 24, '1', 'n', 'y')
(6, 3, 20, '1', 'n', 'y')
(7, 3, 24, '1', 'n', 'y')
(8, 3, 25, '1', 'n', 'y')
(9, 4, 20, '1', 'n', 'y')
(10, 4, 21, '1', 'n', 'y')
(11, 4, 23, '1', 'n', 'y')
(12, 4, 24, '1', 'n', 'y')

上面我们有3个订单(order_id 2,3和4)。

我需要获得所有具有product_id = 21但不是product_id = 20的订单的order_id(订单中的其他product_id无关紧要 - 我只对21和20感兴趣)。

然后我需要知道有两个产品_20和21的订单(同样,订单中的其他产品也无关紧要)。

这是立即提取特定产品的所有订单的基本查询:

SELECT order_id FROM survey_product 
WHERE product_id = 20
AND (pq1 = '1' OR pq1 = '2' OR pq1 = '3')

关于如何实现这一目标的任何想法?

我试过了

SELECT order_id FROM survey_product 
WHERE product_id IN (20) AND product_id NOT IN (21)
AND (pq1 = '1' OR pq1 = '2' OR pq1 = '3')

但它也排除了所有其他价值。

非常感谢。

2 个答案:

答案 0 :(得分:4)

在这种情况下使用JOIN而不是嵌套查询通常是有益的:

    SELECT sp.order_id
      FROM survey_product AS sp
 LEFT JOIN 
           (SELECT order_id FROM survey_product WHERE product_id = 20) AS sp_t
        ON sp.order_id = sp_t.order_id
     WHERE sp_t.order_id IS NULL
       AND sp.product_id = 21
       AND sp.pq1 IN ('1', '2', '3')

order_idproduct_id同时包含20和21的查询类似:您只需使用 INNER JOIN sp_t.order_id没有检查IS NULL。或者只是保持原样,但如果你是懒惰的话,请用IS NOT NULL替换{{1}} - 但我认为这样会慢一些。 )

这是一个SQL fiddle来玩。

答案 1 :(得分:3)

我通常通过在WHERE条件中使用嵌套查询来执行此操作:

SELECT order_id
FROM survey_product
WHERE product_id = 21
AND pq1 IN ('1', '2', '3')
AND order_id NOT IN (
    SELECT order_id 
    FROM survey_product
    WHERE product_id = 20)

基本上,您会从order_id的行中找到所有product_id = 20,然后将其从主查询中排除,即您从order_id的行中选择product_id = 21但是不属于子查询产生的order_id