动态 MySQL 查询错误

Dynamic MySQL Query error

MySLQ新手看这里。我正在尝试编写一个查询来转换大量 table 天气数据。我的意思是以下内容。我有一个包含三列的 table "weatherData":1. "timeStamp"、2. "stationID"(不同气象站的 ID)和 3. "temperature"(测量的温度在各自的时间由各自的车站)。我希望我的查询 return 作为第一列 "timeStamp" 然后 n 列命名为包含测量温度的站点 ID(n 是站点的数量)。站点数量较多(n 约为 4000),温度记录时间为 5 分钟。间隔超过 2.5 年,因此 "weatherData" 有大约 700 万行。

我尝试的第一件事是生成列 "manually":

SELECT 
  timeStamp,
  SUM(CASE WHEN stationID=1253 THEN temperature ELSE 0 END) AS '1253',
  SUM(CASE WHEN stationID=1254 THEN temperature ELSE 0 END) AS '1254',
  SUM(CASE WHEN stationID=1255 THEN temperature ELSE 0 END) AS '1255',
  SUM(CASE WHEN stationID=1256 THEN temperature ELSE 0 END) AS '1256',
  SUM(CASE WHEN stationID=1257 THEN temperature ELSE 0 END) AS '1257',
  SUM(CASE WHEN stationID=1258 THEN temperature ELSE 0 END) AS '1258'
FROM weatherData
GROUP BY timeStamp

这按预期工作,但添加所有站点会使它成为一个长查询。然后我尝试动态生成查询如下:

SET @query = NULL;
SELECT GROUP_CONCAT(
  DISTINCT CONCAT( 
    'SUM(',
      'CASE WHEN stationID = ',stationID,' THEN temperature ELSE 0 END',
    ') AS "',stationID,'"'  
  )      
)

INTO @query 
FROM weatherData;

SET @query  = CONCAT(
  'SELECT temperature, ',@query,
  'FROM weatherData',
  'GROUP BY timeStamp'  
);

PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

这给了我以下错误:

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 'weatherData GROUP BY timeStamp' at line 1

奇怪的是,当我生成一个较小的 table 时,它仅包含来自 weatherData 的最多 14 个气象站的数据,并且 运行 上面的 "dynamic" 查询针对这个较小的 table 它工作得很好。因此,只有当我包含来自超过 14 个站点的数据时它才会起作用,并且它不依赖于包含哪些特定站点。 "manual" 查询始终有效,无论包含多少个站点。这里有什么问题?

第二个奇怪的事情是,当包含(相同的)14 个站点时,第一个查询花费的时间明显更长,我本以为这些查询是等价的。我使用的是最新的免费版本 "Toad for MySQL".

至于现在你有一个缺少空格的问题。在 FROM 和 GROUP BY 子句之前添加它们。

SET @query  = CONCAT(
  'SELECT temperature, ',@query,
  ' FROM weatherData', -- added space
  ' GROUP BY timeStamp' -- added space
);

不过,如果您的 GROUP_CONCAT 足够大(> 1024 个字符)并且您的设置是默认设置,它会截断您的 @query 变量并可能导致您的查询出错。要检查是否是这种情况 - 当您的动态变大时,添加一个 SELECT @query 用于调试目的。


我相信我最近的回答将解决您的问题。我已经介绍了 GROUP_CONCAT 最大长度设置的问题,以及通过在执行之前调查字符串来调试动态查询。

要查看它,请单击此处:MySQL Dynamic Pivot Query with over 3000 columns