MySLQ新手在这里。我正在尝试编写一个查询来旋转大型天气数据表。我的意思是以下。我有一张桌子" weatherData"有三列:1。" timeStamp",2。" stationID" (不同气象站的ID)和3."温度" (各个站在各个时间测量的温度)。我希望我的查询返回第一列" timeStamp"然后n列命名为包含测量温度的站ID(n是站点数)。有大量的站(n约为4000),温度记录在5分钟。间隔超过2。5年,所以" weatherData"有大约700万行。
我尝试的第一件事是生成列"手动":
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;
这给了我以下错误:
您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便使用正确的语法 靠近' weatherData GROUP BY timeStamp'在第1行
奇怪的是,当我生成一个较小的表格时,它只包含来自weatherData的多达14个气象站的数据并运行上述"动态"在这个较小的表上查询它完全正常。因此,当我包含来自超过14个站的数据并且它不依赖于包括哪个特定站时,它仅起作用。 "手册"无论包含多少个站,查询始终有效。这是什么问题?
第二个奇怪的是,当包括(相同的)14个站时,第一个查询需要更长的时间,我原以为这些查询是等价的。我正在使用最新的免费版本" Toad for MySQL"。
答案 0 :(得分:0)
至于现在你有缺少空格的问题。在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
最大长度设置问题以及通过在字符串执行之前调查字符串来调试动态查询。