具有动态列名的MySQL查询

具有动态列名的MySQL查询,mysql,Mysql,我有一个包含以下列的源表: 我还有一个目标表,如下所示: 目标表有1440行,其中分钟列已填充(一天中每分钟1行) 对于源表中的每一行,我需要在目标表中为相应的频道(总共有10个频道)填写一个“1”,在StartTime和FinishTime之间每分钟填写一次 我只是在MySQL Workbench中执行此操作(这是一个一次性查询)。我的野兽方法是什么 谢谢 -Scott伪代码: SELECT DISTINCT ChannelNumber FROM source while ($row =

我有一个包含以下列的源表:

我还有一个目标表,如下所示:

目标表有1440行,其中分钟列已填充(一天中每分钟1行)

对于源表中的每一行,我需要在目标表中为相应的频道(总共有10个频道)填写一个“1”,在StartTime和FinishTime之间每分钟填写一次

我只是在MySQL Workbench中执行此操作(这是一个一次性查询)。我的野兽方法是什么

谢谢

-Scott

伪代码:

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问题。