2

我有 2 个表,Products 和 Genre。在 products 表中,它的所有产品信息包括两个流派(genre_id 和genre_id2),只有第一个是必需的,所以第二个可能有空值

在流派表中,我有所有可能的流派名称,其 ID 与产品表的流派 ID 相关

餐桌用品
--------------
id product_name 流派_id 流派_id2
-------------------------------------------------
1 产品 1 2
2 产品2 2
3 产品3 1 4
4 产品4 3 4

表类型
------------
id 流派名称
-------------------------------------------------
1 类型1
2 流派2
3 流派3
4 流派4

我想选择所有不同的类型,看看我有多少该类型的产品

像这样的东西

结果
------
流派 ID 计数
----------------------
    1 2
    2 2
    3 1
    4 2

我有这个声明

SELECT DISTINCT p.genre_id AS genre, g.genre_name,  COUNT(p.genre_id) AS cnt
FROM products AS p
JOIN genre AS g
ON p.genre_id=g.id
GROUP BY genre_id
ORDER BY cnt DESC

但仅适用于genre_id,我不知道如何在此语句中合并genre_id2 并添加与genre_id 一致的计数并列出不同的计数

4

3 回答 3

3
SELECT  a.ID, COUNT(DISTINCT b.ID) + COUNT(DISTINCT c.ID)
FROM    Genre a
        LEFT JOIN products b
            ON a.ID = b.genre_id
        LEFT JOIN products c
            ON a.ID = c.genre_id2
GROUP BY a.ID

genre_id and genre_ID2警告:如果您有相同前任的记录,这将不起作用

5     product5            1            1
于 2013-04-25T00:16:27.407 回答
2

鉴于您有genre要加入的表格,“明显”的解决方案是:

SELECT genre.id AS genre, COUNT(products.id) AS n
FROM genre
  LEFT JOIN products ON genre.id IN (genre_id, genre_id2)
GROUP BY genre.id

SQLFiddle 演示

但是,如果您不这样做,您仍然可以使用UNION

SELECT genre, COUNT(*) as n
FROM
  (SELECT id, genre_id AS genre FROM products
   WHERE genre_id IS NOT NULL
   UNION
   SELECT id, genre_id2 AS genre FROM products
   WHERE genre_id2 IS NOT NULL) AS foo
GROUP BY genre

SQLFiddle 演示


编辑:UNION方法不会(也不能)返回任何计数为 0 的行。“明显”方法可以,因为我使用了LEFT JOIN. 如果您不想要它们,您也可以通过将 替换LEFT JOINJOIN.


编辑2:使用适当的索引(每个genre_id和一个genre_id2),并根据实际数据集的大小和内容,使用依赖子查询的以下解决方案可能比上述任何一个更有效:

SELECT genre.id AS genre,
  (SELECT COUNT(*) FROM products WHERE genre.id = genre_id) +
  (SELECT COUNT(*) FROM products WHERE genre.id = genre_id2) AS n
FROM genre

要消除计数为零的行,只需坚持

HAVING n > 0

在查询结束时。(SQLFiddle 演示)这实际上是一种用于过滤掉此类行的通用方法。

我没有将此与JW 的解决方案进行基准测试,以查看哪个更有效,因为这需要一些实际数据。如果您的数据集相当小,则无论哪种方式都可能无关紧要。

(结果将很大程度上取决于 MySQL 对其优化的程度:LEFT JOIN如果天真地执行,JW 的嵌套 s 在大型数据集上可能会变得非常慢,但我不确定 MySQL 是否足够聪明,不会这样做。同时,我的依赖子查询可能不会得到太多优化,但只要有必要的索引,即使是简单的执行也应该相当快。)


编辑3:请注意,一般来说,这个问题是由糟糕的表格设计引起的。最好将架构更改为使用联结表,如本答案中所述。

这将允许您让每个产品属于任意数量的类型,并且可以让您使用如下简单查询轻松计算每个类型中的产品:

SELECT genre.id AS genre, COUNT(products.id) AS n
FROM genre
  JOIN product_genre ON genre.id   = product_genre.genre
  JOIN products      ON product.id = product_genre.product
GROUP BY genre.id
于 2013-04-25T00:24:38.500 回答
1

用genre_id2写一个类似的语句,和原来的结果做一个union

于 2013-04-25T00:19:14.833 回答