具有动态列名的MySQL查询
我有一个包含以下列的源表: 我还有一个目标表,如下所示: 目标表有1440行,其中分钟列已填充(一天中每分钟1行) 对于源表中的每一行,我需要在目标表中为相应的频道(总共有10个频道)填写一个“1”,在StartTime和FinishTime之间每分钟填写一次 我只是在MySQL Workbench中执行此操作(这是一个一次性查询)。我的野兽方法是什么 谢谢 -Scott伪代码:具有动态列名的MySQL查询,mysql,Mysql,我有一个包含以下列的源表: 我还有一个目标表,如下所示: 目标表有1440行,其中分钟列已填充(一天中每分钟1行) 对于源表中的每一行,我需要在目标表中为相应的频道(总共有10个频道)填写一个“1”,在StartTime和FinishTime之间每分钟填写一次 我只是在MySQL Workbench中执行此操作(这是一个一次性查询)。我的野兽方法是什么 谢谢 -Scott伪代码: SELECT DISTINCT ChannelNumber FROM source while ($row =
SELECT DISTINCT ChannelNumber
FROM source
while ($row = fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber']
$sql = "
UPDATE destination
JOIN source ON StartTime = destination.minutes
AND source.ChannelNumber = $row[ChannelNumber]
SET destination.$channel_col = 1
";
query($sql);
}
通常,您必须关注动态创建一个字符串,该字符串将成为SQL查询,以避免SQL注入,但由于所有数据都来自您的数据库,因此这不应该是一个问题。伪代码:
SELECT DISTINCT ChannelNumber
FROM source
while ($row = fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber']
$sql = "
UPDATE destination
JOIN source ON StartTime = destination.minutes
AND source.ChannelNumber = $row[ChannelNumber]
SET destination.$channel_col = 1
";
query($sql);
}
通常,您必须关注动态创建一个字符串,该字符串将成为SQL查询,以避免SQL注入,但由于所有数据都来自您的数据库,因此这不应该是一个问题。以下是一个MySQL解决方案:
CREATE PROCEDURE PopulateDestinationTable()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE n INT DEFAULT 0;
DECLARE CNumber INT DEFAULT 0;
DECLARE STime INT DEFAULT 0;
DECLARE FTime INT DEFAULT 0;
SELECT COUNT(*) FROM SourceTable INTO n;
SET i = 0;
WHILE i < n DO
SELECT ChanelNumber FROM SourceTable LIMIT i, 1 INTO CNumber;
SELECT StartTime FROM SourceTable LIMIT i, 1 INTO STime;
SELECT FinishTime FROM SourceTable LIMIT i, 1 INTO FTime;
SET @stat1 = CONCAT('UPDATE DestinationTable
SET ', CONCAT('Ch', CNumber), ' = 1 WHERE minutes BETWEEN ? AND ?');
PREPARE statement FROM @stat1;
SET @p1 = STime;
SET @p2 = FTime;
EXECUTE statement USING @p1, @p2;
SET i = i + 1;
END WHILE;
END$$
CREATE PROCEDURE PopulateDestinationTable()
开始
声明i INT默认值为0;
声明n INT默认值为0;
声明CNumber INT默认值为0;
声明STime INT默认值为0;
声明FTime INT默认值为0;
从SourceTable中选择COUNT(*)进入n;
设置i=0;
而我
从SourceTable LIMIT i中选择ChanelNumber,1进入CNNumber;
从SourceTable LIMIT i中选择StartTime,1进入时间;
从SourceTable LIMIT i中选择FinishTime,1进入FTime;
设置@stat1=CONCAT('updatedestinationtable
SET',CONCAT('Ch',CNumber),'=1,其中分钟介于?和?');
编制@stat1的报表;
设置为p1=时间;
设置@p2=FTime;
使用@p1、@p2执行语句;
设置i=i+1;
结束时;
结束$$
另外,在创建存储过程时不要忘记更改分隔符:)以下是一个MySQL解决方案:
CREATE PROCEDURE PopulateDestinationTable()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE n INT DEFAULT 0;
DECLARE CNumber INT DEFAULT 0;
DECLARE STime INT DEFAULT 0;
DECLARE FTime INT DEFAULT 0;
SELECT COUNT(*) FROM SourceTable INTO n;
SET i = 0;
WHILE i < n DO
SELECT ChanelNumber FROM SourceTable LIMIT i, 1 INTO CNumber;
SELECT StartTime FROM SourceTable LIMIT i, 1 INTO STime;
SELECT FinishTime FROM SourceTable LIMIT i, 1 INTO FTime;
SET @stat1 = CONCAT('UPDATE DestinationTable
SET ', CONCAT('Ch', CNumber), ' = 1 WHERE minutes BETWEEN ? AND ?');
PREPARE statement FROM @stat1;
SET @p1 = STime;
SET @p2 = FTime;
EXECUTE statement USING @p1, @p2;
SET i = i + 1;
END WHILE;
END$$
CREATE PROCEDURE PopulateDestinationTable()
开始
声明i INT默认值为0;
声明n INT默认值为0;
声明CNumber INT默认值为0;
声明STime INT默认值为0;
声明FTime INT默认值为0;
从SourceTable中选择COUNT(*)进入n;
设置i=0;
而我
从SourceTable LIMIT i中选择ChanelNumber,1进入CNNumber;
从SourceTable LIMIT i中选择StartTime,1进入时间;
从SourceTable LIMIT i中选择FinishTime,1进入FTime;
设置@stat1=CONCAT('updatedestinationtable
SET',CONCAT('Ch',CNumber),'=1,其中分钟介于?和?');
编制@stat1的报表;
设置为p1=时间;
设置@p2=FTime;
使用@p1、@p2执行语句;
设置i=i+1;
结束时;
结束$$
注意:在创建存储过程时,不要忘记更改分隔符:)我将PHP代码从@peter bowers修改为此,并使其正常工作:
<?php
$mysqli = new mysqli("ip", "user", "pass", "db");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$res = $mysqli->query("update scott_test set Ch1 = null, Ch2 = null, Ch3 = null, Ch4 = null, Ch5 = null, Ch6 = null, Ch7 = null, Ch8 = null, Ch9 = null, Ch10 = null");
$res = $mysqli->query("SELECT TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS StartTime,
CEIL(FaxDuration/60)+ TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS FinishTime,
ChannelNumber
FROM
fax_received
WHERE
DATE(TimeReceived) = DATE((NOW() - INTERVAL 3 DAY))");
while ($row = $res->fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber'];
$start_min = $row['StartTime'];
$end_min = $row['FinishTime'];
$sql = "UPDATE scott_test
SET $channel_col = 1
WHERE minutes between ($start_min, $end_min);
$mysqli->query($sql);
}
?>
我将PHP代码从@peter bowers修改为以下内容,并使其正常工作:
<?php
$mysqli = new mysqli("ip", "user", "pass", "db");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$res = $mysqli->query("update scott_test set Ch1 = null, Ch2 = null, Ch3 = null, Ch4 = null, Ch5 = null, Ch6 = null, Ch7 = null, Ch8 = null, Ch9 = null, Ch10 = null");
$res = $mysqli->query("SELECT TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS StartTime,
CEIL(FaxDuration/60)+ TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS FinishTime,
ChannelNumber
FROM
fax_received
WHERE
DATE(TimeReceived) = DATE((NOW() - INTERVAL 3 DAY))");
while ($row = $res->fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber'];
$start_min = $row['StartTime'];
$end_min = $row['FinishTime'];
$sql = "UPDATE scott_test
SET $channel_col = 1
WHERE minutes between ($start_min, $end_min);
$mysqli->query($sql);
}
?>
填写开始时间、结束时间或两者之间的所有内容?目标表中有多少个频道列?只需9或是继续?您使用什么语言访问mysql?PHP?参见规范化。b[e]st方法是省去目标表。填写开始时间、结束时间或两者之间的所有内容?目标表中有多少个通道列?只需9或是继续?您使用什么语言访问mysql?PHP?参见规范化。b[e]st方法是省去目标表。我希望有一个直接的SQL解决方案,但这样就可以了。我创建了一个与之匹配的小PHP脚本,实现了这一点。我再次回顾这一点,我认为它并没有达到我需要的效果。好像只在频道忙的第一分钟更新,对吗?我需要在开始时间和结束时间之间的所有分钟内更新它。我修改了它以反映我的原始SQL(即使有@Aleksandar Miladinovic的建议,它仍然会在存储过程中给我一个错误),并让它运行。我将发布我的最后一个脚本。如果上面的伪代码让你得到了有效的答案,请将此标记为已接受的答案…不应该是已接受的答案,这是PHP,而不是Mysql。我希望有一个直接的SQL解决方案,但这样就可以了。我创建了一个与之匹配的小PHP脚本,实现了这一点。我再次回顾这一点,我认为它并没有达到我需要的效果。好像只在频道忙的第一分钟更新,对吗?我需要在开始时间和结束时间之间的所有分钟内更新它。我修改了它以反映我的原始SQL(即使有@Aleksandar Miladinovic的建议,它仍然会在存储过程中给我一个错误),并让它运行。我将发布我的最后一个脚本。如果上面的伪代码让你得到了有效的答案,请将此标记为已接受的答案…不应该是已接受的答案,这是PHP,不是Mysql。这是一个Mysql问题。这是一个Mysql问题。