【问题标题】:Multiple conditions on the joined table when using group by使用 group by 时连接表上的多个条件
【发布时间】:2013-06-14 02:48:17
【问题描述】:

我有两张桌子:

产品

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)。我可以轻松地创建一个查询,该查询将返回具有 both 尺寸 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(...) 但我无法得到任何东西工作。提前谢谢各位。

【问题讨论】:

  • 你的输出应该是什么样的。

标签: mysql sql join group-by


【解决方案1】:

由于您需要 1 和 3,因此您需要 COUNTsize_ids,即 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。让我知道它是否适合你。

【讨论】:

  • 这正是我正在寻找的那种简单的解决方案。谢谢!
【解决方案2】:

如果 group_concat 在 PostgreSQL 中的工作方式与它在 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 

【讨论】:

    【解决方案3】:

    谈到性能,最好先过滤到某个 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);
    

    谦虚的建议,用更多的数据做一些测试(:

    【讨论】:

      【解决方案4】:
      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;
      

      【讨论】:

        猜你喜欢
        • 2017-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-03
        • 1970-01-01
        相关资源
        最近更新 更多