如何在准备好的MySQL语句中使用group concat?
我有以下产品数据表:如何在准备好的MySQL语句中使用group concat?,mysql,sql,prepared-statement,group-concat,Mysql,Sql,Prepared Statement,Group Concat,我有以下产品数据表: +--------+--------+------------+ | item_id| amount | date | +--------+--------+------------+ | 4 | 100 | 01-04-2020 | | 6 | 200 | 01-04-2020 | | 9 | 300 | 01-04-2020 | | 4 | 400 | 01-04-2020 | | 4
+--------+--------+------------+
| item_id| amount | date |
+--------+--------+------------+
| 4 | 100 | 01-04-2020 |
| 6 | 200 | 01-04-2020 |
| 9 | 300 | 01-04-2020 |
| 4 | 400 | 01-04-2020 |
| 4 | 300 | 02-04-2020 |
| 6 | 150 | 02-04-2020 |
| 6 | 150 | 02-04-2020 |
| 9 | 700 | 02-04-2020 |
+--------+--------+------------+
我想进行一个查询,以旋转此表,使ItemId
位于列侧,显示所有项目的总和:
+------------+-----+-----+-----+
| date | 4 | 6 | 9 |
+------------+-----+-----+-----+
| 01-04-2020 | 400 | 200 | 400 |
| 02-04-2020 | 300 | 300 | 700 |
+------------+-----+-----+-----+
我能够编写一个查询来实现这一点:
SELECT
date,
SUM(IF(item_id = '1', item_record.amount, NULL)) AS 1,
SUM(IF(item_id = '2', item_record.amount, NULL)) AS 2,
SUM(IF(item_id = '3', item_record.amount, NULL)) AS 3,
COUNT(*) AS Total
FROM item_record
GROUP BY date WITH ROLLUP
但是查询被硬编码为只显示带有item\u id
1、2和3的列。我需要让它充满活力
在StackOverflow周围搜索时,我遇到了。按照公认的答案,我试着把它写成一份事先准备好的声明
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'SUM(IF(item_record.item_id = "',item_record.item_id,'", item_record.amount, NULL))
AS ',item_record.item_id
)
) INTO @sql
FROM item_record;
SET @sql =
CONCAT('SELECT date,
',@sql,',
COUNT(*) AS Total
FROM item_record
GROUP BY date WITH ROLLUP
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
但我遇到了一个错误:
SQL错误[1064][42000]:您的SQL语法有错误;
查看与您的MySQL服务器版本对应的手册,了解要使用的正确语法
我哪里做错了?这看起来只是一个语法错误,但我已经做了几个小时了,仍然不知道发生了什么 您的原始查询已出现语法错误。如果您试图执行它,您会得到与预处理语句解决方案相同的错误: 您的SQL语法有错误;请查看与MySQL服务器版本对应的手册,以了解可在'1'附近使用的正确语法
SUM(IF(item_id = '2', item_record.amount, NULL)) AS 2,
SUM(IF(item_id' at line 3
问题是resultset中列别名的名称:1
(或任何以数字开头的名称)不是有效标识符-除非用反勾号将其括起来
我将您的代码表述为:
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('SUM(CASE WHEN item_id = ', item_id, ' THEN amount END) AS `', item_id, '`')
) INTO @sql
FROM item_record;
SET @sql = CONCAT(
'SELECT date, ',
@sql,
', COUNT(*) AS Total FROM item_record GROUP BY date WITH ROLLUP'
);
请注意,这使用标准的
CASE
表达式,而不是IF()
(两者在MySQL中都有效)。此外,这会将item\u id
视为一个数字而不是一个字符串,因为它看起来就是这样。您的原始查询已经是语法错误了。如果您试图执行它,您会得到与预处理语句解决方案相同的错误:
您的SQL语法有错误;请查看与MySQL服务器版本对应的手册,以了解可在'1'附近使用的正确语法
SUM(IF(item_id = '2', item_record.amount, NULL)) AS 2,
SUM(IF(item_id' at line 3
问题是resultset中列别名的名称:1
(或任何以数字开头的名称)不是有效标识符-除非用反勾号将其括起来
我将您的代码表述为:
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('SUM(CASE WHEN item_id = ', item_id, ' THEN amount END) AS `', item_id, '`')
) INTO @sql
FROM item_record;
SET @sql = CONCAT(
'SELECT date, ',
@sql,
', COUNT(*) AS Total FROM item_record GROUP BY date WITH ROLLUP'
);
请注意,这使用标准的
CASE
表达式,而不是IF()
(两者在MySQL中都有效)。此外,这将项目id
视为一个数字而不是字符串-因为它看起来就是这样的。坦白说,如果应用程序无法将以下内容转换为漂亮的内容,那么它可能就不值得麻烦了
DROP TABLE IF EXISTS product_data;
CREATE TABLE product_data
(id SERIAL PRIMARY KEY
,item_id INT NOT NULL
,amount INT NOT NULL
,date DATE NOT NULL
);
INSERT INTO product_data VALUES
(1,4,100,'2020-04-01'),
(2,6,200,'2020-04-01'),
(3,9,300,'2020-04-01'),
(4,4,400,'2020-04-01'),
(5,4,300,'2020-04-02'),
(6,6,150,'2020-04-02'),
(7,6,150,'2020-04-02'),
(8,9,700,'2020-04-02');
SELECT item_id
, date
, SUM(amount) x
FROM product_data
GROUP
BY date
, item_id;
+---------+------------+------+
| item_id | date | x |
+---------+------------+------+
| 4 | 2020-04-01 | 500 |
| 6 | 2020-04-01 | 200 |
| 9 | 2020-04-01 | 300 |
| 4 | 2020-04-02 | 300 |
| 6 | 2020-04-02 | 300 |
| 9 | 2020-04-02 | 700 |
+---------+------------+------+
坦白地说,如果应用程序无法将以下内容转换成漂亮的东西,那么它可能就不值得麻烦了
DROP TABLE IF EXISTS product_data;
CREATE TABLE product_data
(id SERIAL PRIMARY KEY
,item_id INT NOT NULL
,amount INT NOT NULL
,date DATE NOT NULL
);
INSERT INTO product_data VALUES
(1,4,100,'2020-04-01'),
(2,6,200,'2020-04-01'),
(3,9,300,'2020-04-01'),
(4,4,400,'2020-04-01'),
(5,4,300,'2020-04-02'),
(6,6,150,'2020-04-02'),
(7,6,150,'2020-04-02'),
(8,9,700,'2020-04-02');
SELECT item_id
, date
, SUM(amount) x
FROM product_data
GROUP
BY date
, item_id;
+---------+------------+------+
| item_id | date | x |
+---------+------------+------+
| 4 | 2020-04-01 | 500 |
| 6 | 2020-04-01 | 200 |
| 9 | 2020-04-01 | 300 |
| 4 | 2020-04-02 | 300 |
| 6 | 2020-04-02 | 300 |
| 9 | 2020-04-02 | 700 |
+---------+------------+------+
认真考虑应用程序代码中的数据显示问题,为了人类的爱,将日期存储为日期。所建查询是错误的。
CONCAT
的结果将是SELECT date SUM(…
,因此缺少一个逗号。但我强烈支持@Strawberry@GhostGambler实际上,我在实际查询中有一个逗号。我在复制粘贴时搞砸了。我已经更新了question@Strawberry对于应用层,我使用Metabase,它直接使用MySQL进行数据显示我的实际查询时间更长。认真考虑应用程序代码中的数据显示问题,为了人类的爱,将日期存储为日期。所建查询是错误的。<代码> CONTAAT/<代码>的结果是<代码>选择日期和。(…,因此缺少一个逗号。但我强烈支持@Strawberry@GhostGambler实际上,我在实际查询中有一个逗号。我在复制粘贴时搞砸了。我已经更新了question@Strawberry对于应用层,我使用Metabase,它直接使用MySQL进行数据显示便于查看。我的实际查询要长得多。。