我有一个名为'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')
但它也排除了所有其他价值。
非常感谢。
答案 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_id
中product_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
。