MySQL将具有相同ID的多行值复制到新列中?

时间:2011-08-19 09:13:15

标签: mysql sql

ItemID    |    File                    

1           /storage/somefile1.jpg
1           /storage/somefile2.jpg
1           /storage/somefile3.jpg
1           /storage/somefile5.jpg  

2           /storage/somerandomfile.jpg
2           /storage/anotherrandomfile.jpg
2           /storage/yetanotherrandomfile.jpg
2           /storage/somefile.jpg  

我想为每个文件创建一个新列,而不是每个文件有一行。如:

ItemID    |    File                     |    File2                        | File3 etc...

1           /storage/somefile1.jpg      |   /storage/somefile2.jpg        |   /storage/..


2           /storage/somerandomfile.jpg |  /storage/anotherrandomfile.jpg | /storage/..

有没有办法通过查询自动执行此操作?

5 个答案:

答案 0 :(得分:0)

没有。你无法在飞行中做到这一点(改变mysql架构)。

答案 1 :(得分:0)

根据我对该问题的评论,您可以使用所需的架构创建一个新表,并运行类似的东西(假设PDO):

<?php
$db->beginTransaction();
$query = $db->query('SELECT ItemID, GROUP_CONCAT(File SEPARATOR \'|$|\') AS Files FROM Table GROUP BY ItemID');
// Use a string that cant appear as part of the filename as the separator
$sth = $db->prepare('INSERT INTO NewTable (ItemID, File1, File2, File3) VALUES (:ItemID, :File1, :File2, :File3)');
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $row) {
    $files = explode('|$|', $row['Files']);
    $sth->execute(array(
        'ItemID' => $row['ItemID'],
        'File1' => isset($files[0]) ? $files[0] : NULL,
        'File2' => isset($files[1]) ? $files[1] : NULL,
        'File3' => isset($files[2]) ? $files[2] : NULL,
    ));
}
$db->commit();

但是,我确实认为您当前的架构设计更好。你为什么要改变它?

答案 2 :(得分:0)

在看到您的评论并且您只想尝试制作CSV之后,您可以执行以下操作:

<?php
$query = $db->query('SELECT ItemID, GROUP_CONCAT(File SEPARATOR \'|$|\') AS Files FROM Table GROUP BY ItemID');
// Use a string that cant appear as part of the filename as the separator
$fh = fopen('items.csv', 'w');
foreach ($query->fetchAll(PDO::FETCH_ASSOC) as $row) {
    $files = explode('|$|', $row['Files']);
    fputcsv($fh, array_merge(array($row['ItemID']), $files));
}
fclose($fh);

答案 3 :(得分:0)

如果要在SQL中生成CSV,可以使用以下查询作为起点:

SELECT CONCAT_WS(',', ItemID, GROUP_CONCAT(File ORDER BY File SEPARATOR ',')) AS FullCSVRow
FROM ItemToFile
GROUP BY ItemID

...返回:

FullCSVRow
1,/storage/somefile1.jpg,/storage/somefile2.jpg,/storage/somefile3.jpg,/storage/somefile5.jpg
2,/storage/somerandomfile.jpg,/storage/somerandomfile.jpg,/storage/somerandomfile.jpg,/storage/somerandomfile.jpg
3,/storage/file-1-of-2.jpg,/storage/file-2-of-2.jpg

如果您使用的是PHP,则可以完全控制您的查询以及构建方式。您无需更改数据库设计。

答案 4 :(得分:0)

SELECT
   ItemID,

   ( SELECT t2.File FROM ( SELECT @row := @row + 1 AS r, File FROM my_table AS t3
     JOIN ( SELECT @row := 0 ) AS init
     WHERE t1.ItemID = t3.ItemID ORDER BY t3.File ) AS t2 WHERE t2.r = 1 ),

   ( SELECT t2.File FROM ( SELECT @row := @row + 1 AS r, File FROM my_table AS t3
     JOIN ( SELECT @row := 0 ) AS init
     WHERE t1.ItemID = t3.ItemID ORDER BY t3.File ) AS t2 WHERE t2.r = 2 ),

   ( SELECT t2.File FROM ( SELECT @row := @row + 1 AS r, File FROM my_table AS t3
     JOIN ( SELECT @row := 0 ) AS init
     WHERE t1.ItemID = t3.ItemID ORDER BY t3.File ) AS t2 WHERE t2.r = 3 ),

   ( SELECT t2.File FROM ( SELECT @row := @row + 1 AS r, File FROM my_table AS t3
     JOIN ( SELECT @row := 0 ) AS init
     WHERE t1.ItemID = t3.ItemID ORDER BY t3.File ) AS t2 WHERE t2.r = 4 )

   FROM my_table AS t1