Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在准备好的MySQL语句中使用group concat?_Mysql_Sql_Prepared Statement_Group Concat - Fatal编程技术网

如何在准备好的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进行数据显示便于查看。我的实际查询要长得多。。