我有以下SQL:
SELECT `table1`.`value`, `table2`.*
FROM `table2`
INNER JOIN `table1` ON `table2`.`product_id` = `table1`.`entity_id`
WHERE `table2`.`created_at` > '2012-04-23' and
(`table1`.`value` = 264 OR `table1`.`value` = 260)
order by order_id
返回这样的结果集(这只是返回结果的一部分):
value order_id ...
260 1234
260 1235
260 1236
264 1236
260 1237
260 1238
260 1239
264 1239
264 1240
260 1241
我想要的是一个查询,它将获取这些结果,并且只返回order_id包含值260和264的订单。基于此示例,我要查找的最终结果是
260 1236
264 1236
260 1239
264 1239
我的想法是这可以用一个子集完成,但我不完全确定完成它的细节。
答案 0 :(得分:5)
这可以通过relational division完成:
select r.order_id from (
select
dividend.*
from your_table_or_query as dividend -- assumes no duplicates in `dividend`; use `distinct` if there are any
inner join divisor
on dividend.value = divisor.value
) as r
group by r.order_id
having count(*) = (select count(*) from divisor);
结果:
+----------+
| order_id |
+----------+
| 1236 |
| 1239 |
+----------+
2 rows in set (0.00 sec)
您的查询为your_table_or_query
和
select 260 as value from dual union select 264 as value from dual
是divisor
。
这将返回订单ID 1236和1239;然后,他们可以join
到原始查询,以获取具有这些订单ID的所有行,如果这是您想要的。
完整查询以及插入语句:
create table divisor (value int);
insert into divisor values (260), (264);
create table your_table_or_query (value int, order_id int);
insert into your_table_or_query values (260, 1234), (260, 1235), (260, 1236), (264, 1236), (260, 1237), (260, 1238), (260, 1239), (264, 1239), (264, 1240), (260, 1241);
select y.* from (
select r.order_id from (
select
dividend.*
from your_table_or_query as dividend
inner join divisor
on dividend.value = divisor.value
) as r
group by r.order_id
having count(*) = (select count(*) from divisor)
) as quotient
inner join your_table_or_query y
on quotient.order_id = y.order_id;
结果:
+-------+----------+
| value | order_id |
+-------+----------+
| 260 | 1236 |
| 264 | 1236 |
| 260 | 1239 |
| 264 | 1239 |
+-------+----------+
4 rows in set (0.00 sec)
答案 1 :(得分:1)
这个怎么样?
SELECT table1.value, table2.*
FROM table2
INNER JOIN table1
ON table2.product_id = table1.entity_id
WHERE table2.created_at > '2012-04-23' AND
(table1.value = 264 OR table1.value = 260)
AND table2.order_id IN (
SELECT table2.order_id
FROM table2
INNER JOIN table1
ON table2.product_id = table1.entity_id
WHERE table2.created_at > '2012-04-23' AND
(table1.value = 264 OR table1.value = 260)
GROUP BY table2.order_id
HAVING COUNT(*) = 2
)
(抱歉省略撇号,我不知道这个字段中的mysql要求是什么;这个语法符合ms-sql)
答案 2 :(得分:1)
这将返回一个包含值260和264的订单列表 - 如果有人只需要此结果而不是每个值的重复结果:
SELECT `table2`.*
FROM `table2`
INNER JOIN `table1` as `table1_264`
ON `table2`.`product_id` = `table1_264`.`entity_id`
AND `table1_264`.`value` = 264
INNER JOIN `table1` as `table1_260`
ON `table2`.`product_id` = `table1_260`.`entity_id`
AND `table1_260`.`value` = 260
WHERE `table2`.`created_at` > '2012-04-23'
order by order_id
<小时/> 或者如果有人想要更快的解决方案而没有昂贵的
having
条款(当然,你可以存储查询或使用CTE而不是重复它)
SELECT 264 as `value`, `table2`.*
FROM `table2`
INNER JOIN `table1` as `table1_264` ON `table2`.`product_id` = `table1_264`.`entity_id` AND `table1_264`.`value` = 264
INNER JOIN `table1` as `table1_260` ON `table2`.`product_id` = `table1_260`.`entity_id` AND `table1_260`.`value` = 260
WHERE `table2`.`created_at` > '2012-04-23'
UNION ALL
SELECT 260, `table2`.*
FROM `table2`
INNER JOIN `table1` as `table1_264` ON `table2`.`product_id` = `table1_264`.`entity_id` AND `table1_264`.`value` = 264
INNER JOIN `table1` as `table1_260` ON `table2`.`product_id` = `table1_260`.`entity_id` AND `table1_260`.`value` = 260
WHERE `table2`.`created_at` > '2012-04-23'
order by order_id
答案 3 :(得分:-1)
SELECT `table1`.`value`, `table2`.*
FROM `table1`
LEFT JOIN `table2` ON `table1`.`entity_id` = `table2`.`product_id`
WHERE
(`table1`.`value` = 264 OR `table1`.`value` = 260)
AND `table2`.`created_at` > '2012-04-23'
ORDER BY `table2`.order_id
左连接因此它只匹配table1.value结果与匹配并保留其他表中的信息