2017-08-07 125 views
1

銷售數據庫中有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()方法實現這個複雜的語句。

+0

我不認爲'SELECT ... INTO'變量將直接工作在MySQL。但是,爲什麼在給它分配一些東西后立即覆蓋'@ sql'? –

回答

2

對於第一次警告,MySql的GROUP_CONCAT功能默認情況下,僅限於1024

您可以增加查詢之前限制使用:

SET @@group_concat_max_len = 32000; 
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語句使用引號()函數:

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;