[英]MySql Distinct values of two different columns of the same table
我有2個表,Products和Genre。在products表中,它關於產品的所有信息包括兩種流派(genre_id和genre_id2),僅第一個是必需的,因此第二個可以具有空值
在流派表中,我具有所有可能的流派名稱,其ID與產品表的流派ID有關
TABLE PRODUCTS -------------- id product_name genre_id genre_id2 ------------------------------------------------- 1 product 1 2 2 product2 2 3 product3 1 4 4 product4 3 4 TABLE GENRE ----------- id genre_name ------------------------------------------------- 1 genre1 2 genre2 3 genre3 4 genre4
我想選擇所有不同的流派,看看我有多少種該流派的產品
像這樣的東西
RESULT ------ genre_id count ----------------------- 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一致的計數並列出不同的計數
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
鑒於您具有要連接的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的行。“ obvious”方法會返回,因為我使用了LEFT JOIN
。 如果你不想讓他們,你也可以通過更換從“明顯”的方法消除它們LEFT JOIN
只是一個JOIN
。
編輯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對其的優化程度:如果天真執行JW的嵌套LEFT JOIN
在大型數據集上可能會變得非常慢,但是我不確定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
用genre_id2編寫類似的語句,並與原始結果進行並集
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.