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
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;
现在我有了所有可能的产品名称(apple apples avocado grapes mango橙子),可以开始重建源表了:
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
......嗯,苹果怎么了? 一个可能的解决方案是将所有的apple替换为apple
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');
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
2条答案
按热度按时间0yycz8jy1#
假设
Product
是一个字符列,并且其中存储了一个“逗号分隔列表”,那么实现指定结果的SQL将非常麻烦。SQL并不是为将逗号分隔列表中的字符串拆分成单独的行而设计的,这种表设计违背了关系数据库设计的最佳实践原则。
我强烈推荐Bill Karwin的优秀著作“SQL反模式:避免数据库编程的陷阱”。第2章“乱穿马路”目前在亚马逊的“往里看”功能中有售...
https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
但是,要回答你所问的问题。有可能达到指定的结果。这将适用于示例情况,但不一定适用于其他更一般的情况:
退货:
这对示例数据有效,但对其他可能的数据无效。(例如,如果逗号分隔的产品列表包含四个项目,或仅包含两个项目。)
如果你有一个单独的表要返回,其中只有一个
Product
......我们可能会在它和问题中显示的表之间使用JOIN,然后使用FIND_IN_SET类型的操作来进行匹配,这会使查询更简单一些。ljsrvy3e2#
你真的真的需要把table修好。也许这就是你在这里努力实现的目标。
我个人会:
。
现在我有了所有可能的产品名称(apple apples avocado grapes mango橙子),可以开始重建源表了:
......嗯,苹果怎么了?
一个可能的解决方案是将所有的apple替换为apple
Mysql的replace是区分大小写的,所以我们从
现在我们可以运行上一个查询的结果:
我们修改的源表:
让我们重新开始
下一个问题会让我很高兴:
瞧