2011-08-19 105 views
1
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行。如:MySQL將具有相同ID的多行值複製到新列中?

ItemID | File      | File2      | File3 etc... 

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


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

有沒有什麼辦法與查詢自動完成這個?

+0

我不這麼認爲。 AFAIK,你將不得不使用一些腳本來創建查詢。你使用什麼編程語言? – shesek

+0

我正在使用PHP 5.2.x –

+0

您的數據庫設計看起來是最佳的。你確定要改變它嗎?你試圖解決什麼確切的問題? –

回答

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); 
0

不,你不能這樣做(改變mysql方案)。

+0

如果我手動創建了新的列和列File1到File5,那麼現有的所有就緒代碼都可以遍歷具有相同ID的每一行,然後將原始列的內容複製到每個新的空列中? –

+0

當然。但是編寫用於填充這些行的腳本會更好。 –

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(); 

不過,我覺得你目前的架構設計是更好。你爲什麼要改變它?

+0

僅用於爲CSV導出準備數據,以便將其導入到不同的CMS中,將所有文件按1 ID進行分組只是使該過程的一部分更容易,即使最終它最終會以類似的模式結束。也許有一種更簡單的方法來製作一個查詢,使其「看起來」,而不是將文件移動到自己的列中。 –

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,您可以完全控制您執行哪些查詢以及如何構建它們。您不需要更改數據庫設計。

+0

這是一個明智的做法,但是如果任何文件名中包含','可能會產生問題,因爲它不會被正確轉義以用於CSV格式 – shesek

+0

@shesek:...並且如果有項目沒有4個文件,就像我的例子。這就是我的意思是「出發點」:)無論如何,我會用PHP來做到這一點。 –

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 
相關問題