MySQL скопировать несколько строк значений с одинаковым идентификатором в новые столбцы? - PullRequest
1 голос
/ 19 августа 2011
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  

Я хочу создать новый столбец для каждого файла вместо 1 строки на файл. Такие как:

ItemID    |    File                     |    File2                        | File3 etc...

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


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

Есть ли способ автоматизировать это с помощью запроса?

Ответы [ 5 ]

0 голосов
/ 19 августа 2011
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
0 голосов
/ 19 августа 2011

Если вы хотите создать свой CSV прямо в SQL, вы можете использовать следующий запрос в качестве отправной точки:

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, у вас есть полный контроль над тем, какие запросы вы делаете и как вы их строите. Вам не нужно менять дизайн БД.

0 голосов
/ 19 августа 2011

После моего комментария по этому вопросу вы можете создать новую таблицу с желаемой схемой и выполнить что-то вроде этого (при условии 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();

Однако я думаю, что ваша текущая схема работаетлучше.Почему вы пытаетесь это изменить?

0 голосов
/ 19 августа 2011

После просмотра вашего комментария и того, что вы просто пытаетесь сделать из него 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);
0 голосов
/ 19 августа 2011

Нет. Вы не можете сделать это (изменить схему MySQL) на лету.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...