准备语句语法错误

时间:2017-08-07 01:44:21

标签: mysql syntax-error prepared-statement pivot-table

销售数据库中有3个表:orders(order_id, user_id, item_id, quantity, date), users(user_id, name, discount_percent) and items(item_id, name, type, price)。我正在尝试按用户分组的每月利润生成一份报告,该日期必须看起来像这样(摘录):

|-------user--------|----------day_1--------|---------day_2---------|---------day_3---------| etc. |

|-user_name_1-|-sum_of_expenses-|-sum_of_expenses-|-sum_of_expenses-| etc. |

|-user_name_2-|-sum_of_expenses-|-sum_of_expenses-|-sum_of_expenses-| etc. |

我使用以下准备好的声明来实现这一目标:

SELECT
    GROUP_CONCAT(DISTINCT CONCAT('SUM(IF(DATE(orders.date) = \'', 
                DATE(orders.date),
                '\', orders.quantity * items.price * (1 - users.discount_percent / 100), 0)) AS ',
                DATE(orders.date))
        ORDER BY DATE(orders.date))
INTO @sql FROM 
    orders;
SET @sql = CONCAT('SELECT users.name, ', @sql, ' FROM 
    users
        INNER JOIN
    orders ON users.user_id = orders.user_id
        INNER JOIN
    items ON orders.item_id = items.item_id
GROUP BY users.name
ORDER BY users.user_id');

PREPARE statement FROM @sql;
EXECUTE statement;
DEALLOCATE PREPARE statement;

出于某种原因,它给了我一个警告:

1 row(s) affected, 1 warning(s): 1260 Row 8 was cut by GROUP_CONCAT()

然后是错误:

Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2015-01-01,SUM(IF(DATE(orders.date) = '2015-01-02', orders.quantity * items.pric' at line 1

我认为这与日期或引号的格式有关,但我输入的所有内容都无法修复。

此外,我正试图弄清楚如何通过php的mysqli prepare()方法实现这个复杂的语句。

2 个答案:

答案 0 :(得分:2)

对于第一个警告,MySql group_concat函数默认限制为1024。

您可以使用以下方法增加查询前的限制:

SET @@group_concat_max_len = 32000;

答案 1 :(得分:0)

每当SQL中出现语法错误时,通过查看生成的最终SQL,用于生成SQL的代码,更容易找到问题。

在这种情况下,我认为您会发现您定义的列别名缺少引号:

SUM(IF(DATE(orders.date) = '2015-01-01', 
       orders.quantity * items.price * (1 - users.discount_percent / 100), 
       0)
) AS 2015-01-01

这不是合法的列别名。你必须在它周围加上引号。

我建议您在创建准备好的SQL语句时使用QUOTE()函数:

SELECT
GROUP_CONCAT(DISTINCT CONCAT('SUM(IF(DATE(orders.date) = ', 
            QUOTE(DATE(orders.date)),
            ', orders.quantity * items.price * (1 - users.discount_percent / 100), 0)) AS ',
            QUOTE(DATE(orders.date)))
    ORDER BY DATE(orders.date))
INTO @sql FROM 
orders;