單位產品計我有這樣的一個表:分割從一個表
Count Product
100 apple, orange, mango
50 apple, grape, avocado
20 orange, apple, avocado
如何選擇獲得這樣每個產品的計數?
Count Product
170 apple
120 orange
100 mango
70 avocado
50 grape
單位產品計我有這樣的一個表:分割從一個表
Count Product
100 apple, orange, mango
50 apple, grape, avocado
20 orange, apple, avocado
如何選擇獲得這樣每個產品的計數?
Count Product
170 apple
120 orange
100 mango
70 avocado
50 grape
假設Product
是字符列,並且「逗號分隔的列表」的值被存儲在它的SQL達到規定的結果是麻煩的。
SQL不是用於將逗號分隔列表中的字符串拆分爲單獨的行。這個表格設計是面對最佳實踐關係數據庫設計原則的。
我強烈建議比爾卡爾文的優秀着作「SQL反模式:避免數據庫編程的陷阱」。第2章「亂穿馬路」,是目前在亞馬遜的「往裏」功能...
https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
然而,要回答你問的問題。可以達到指定的結果。這將爲例如情況下工作,但不一定是其他更一般的情況:
SELECT REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(c.Product
,'Apples','Apple'
),'apple','Apple'
),'orange','Orange'
),'mango','Mango'
),'grapes','Grapes'
),'avocado','Avocado'
) AS `Product`
, SUM(c.Count) AS `Count`
FROM (SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(d.Product,',',n.i),',',-1)) AS `Product`
, d.Count
FROM (SELECT 1 AS i UNION ALL SELECT 2 UNION ALL SELECT 3) n
CROSS
JOIN (-- table of example data
SELECT 100 AS `Count`, 'Apples, orange, mango' AS `Product`
UNION ALL SELECT 50, 'Apples, grapes, avocado'
UNION ALL SELECT 20, 'Orange, apple, avocado'
) d
) c
GROUP
BY REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(c.Product
,'Apples','Apple'
),'apple','Apple'
),'orange','Orange'
),'mango','Mango'
),'grapes','Grapes'
),'avocado','Avocado'
)
ORDER BY 2 DESC, 1 ASC
返回:
Product Count
------- --------
Apple 170
Orange 120
Mango 100
Avocado 70
Grapes 50
該方法適用於例如數據,但不會對其他可能的數據。 (例如,如果用逗號分隔的產品列表中包含四個項目,或者只有兩個項目。)
如果你有隻是個別Product
歸還......我們也許可以使用JOIN一個單獨的表在問題中顯示的表和表之間,並使用FIND_IN_SET類型操作來執行該匹配。這會使查詢變得更簡單一些。
愛那本書! – michelek
你確實需要修復表格。也許這就是你想在這裏實現的。
我個人:
。
CREATE TABLE product
(
id INT(11) UNSIGNED NOT NULL auto_increment,
product VARCHAR(50) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY product (product)
)
engine=innodb
DEFAULT charset=utf8;
現在我把所有可能的產品名稱(蘋果蘋果鱷梨葡萄,芒果橙),可以開始重建你的源表:
SELECT p.product,
Sum(src.count)
FROM product p
LEFT JOIN src
ON src.product REGEXP p.product
GROUP BY p.product
;
--
product Sum(src.count)
apple 170
apples 150
avocado 70
grapes 50
mango 100
orange 120
...嗯什麼與蘋果的?
一個可能的解決方案是,以取代所有的「蘋果」與「蘋果」
SELECT Concat('UPDATE src SET product = Replace(product, \'', p2.product, '\', \'', p1.product, '\');') AS q
FROM product p1
LEFT JOIN product p2
ON p1.product != p2.product
AND p2.product REGEXP p1.product
WHERE p2.product IS NOT NULL
;
--
q
UPDATE src SET product = Replace(product, 'apples', 'apple');
MySQL的更換是大小寫敏感的,所以我們通過
UPDATE src
SET product = Lower(product);
開始,現在我們可以運行結果前面的查詢:
UPDATE src SET product = Replace(product, 'apples', 'apple');
--
2 rows affected
我們修改後的源表:
SELECT * FROM src
;
-
Count Product
100 apple, orange, mango
50 apple, grapes, avocado
20 orange, apple, avocado
讓我們重新開始與
而接下來的查詢就會讓我快樂:
CREATE TABLE inventory AS
SELECT p.product,
Sum(src.count) AS count
FROM product p
LEFT JOIN src
ON src.product REGEXP p.product
GROUP BY p.product
;
SELECT * FROM inventory
;
--
product count
apple 170
avocado 70
grapes 50
mango 100
orange 120
瞧
你有一個產品定義表的地方? – shmosel
我推薦Bill Karwin的優秀書的第2章。 (截至本評論,第2章仍然可以在亞馬遜的「Look Inside」中看到... https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557 – spencer7593
假設產品和它的計數是原子數據,我建議將模式更改爲「(count,product)」元組,而不是使用它們的(合併?)計數來存儲產品列表。 –