我有两张桌子:
产品
id name
1 Product 1
2 Product 2
3 Product 3
products_sizes
id size_id product_id
1 1 1
2 2 1
3 1 2
4 3 2
5 3 3
因此产品1有两种尺寸:1,2。产品2有两种尺寸:1,3。产品3有一种尺寸:3。
我想要做的是构建一个查询,回收同时具有1号和3号尺寸的产品(即产品2)。我可以轻松创建一个查询,以回收两个大小为1和3的产品:
select `products`.id, `products_sizes`.`size_id`
from `products` inner join `products_sizes` on `products`.`id` = `products_sizes`.`product_id`
where products_sizes.size_id IN (1, 3)
group by products.id
当我运行此查询时,我会返回产品1,产品2和产品3。
重申一下,我只想回到产品2.我已经尝试过使用HAVING子句,弄乱了$ ID IN GROUP_CONCAT(...),但是我无法得到任何东西工作。先谢谢你们。
答案 0 :(得分:1)
由于您同时需要1和3,因此您需要COUNT
size_id
IN (1, 3)
并且要求结果为2:
SELECT p.id AS id, p.name AS name
FROM products p, products_sizes s
WHERE p.id = s.product_id AND s.size_id IN (1, 3)
GROUP BY s.product_id
HAVING COUNT(DISTINCT s.size_id) = 2;
查看demo here。让我知道它是否适合你。
答案 1 :(得分:1)
如果group_concat的工作方式与PostgreSQL中的相同,那么这个可能适用于MySQL:
select
product_id
from products
left join ( select group_concat(cast(id as char(5)), ',') as agg1 from sz where id in (1, 3) group by size_id ) as qagg1 on 1=1
left join ( select products_sizes.product_id product_id, group_concat(cast(products_sizes.size_id as char(5)), ',') agg2 from sz where products_sizes.size_id IN (1, 3) group by products_sizes.product_id ) as qagg2 on 1=1
where qagg1.agg1 = qagg2.agg2
group by product_id
这是在PostgreSQL中测试的原始查询:
select
product_id
from pr
left join ( select string_agg(cast(id as char(5)), ',') as agg1 from sz where id in (1, 3) group by size_id ) as qagg1 on 1=1
left join ( select sz.product_id product_id, string_agg(cast(sz.size_id as char(5)), ',') agg2 from sz where sz.size_id IN (1, 3) group by sz.product_id ) as qagg2 on 1=1
where qagg1.agg1 = qagg2.agg2
group by product_id
答案 2 :(得分:0)
谈到性能,首先过滤到某个size_id会很不错:
SELECT STRAIGHT_JOIN
x.id, y.size_id AS size_1, z.size_id AS size_2
FROM (
SELECT * FROM products_sizes
WHERE size_id = 1
) AS y
INNER JOIN products AS x
ON (x.id = y.product_id)
INNER JOIN (
SELECT * FROM products_sizes
WHERE size_id = 3
) AS z
ON (x.id = z.product_id);
谦虚的建议,用更多的数据进行一些测试(:
答案 3 :(得分:0)
select `products`.id, `products_sizes`.`size_id`
from `products` inner join `products_sizes` on `products`.`id` = `products_sizes`.`product_id`
where products_sizes.size_id IN (1, 3)
group by products.id
having count(distinct `products_sizes`.size_id) = 2;