2013-07-11 102 views
0

我需要從MySQL數據庫中導出一個列,每個數據庫只顯示一次條目。因此,如下表所示:單個列的MySQL導出只顯示重複條目一次

id  author(s)    content 
________________________________________ 
1  Bill, Sara, Mike  foo1    
1  Sara     foo2 
2  Bill, Sara, Mike  foo3 
2  Sara     foo4 
3  David     foo5  
3  Mike     foo5  

我需要作者的列表導出爲「比爾,薩拉,邁克,蘇珊」使每名顯示只有一次。

謝謝!

更新:我知道這是不可能的,所以我將不得不接受一個導出列表,它只是消除了柱內的任何確切的重複,所以輸出會是這樣:比爾,薩拉,麥克,薩拉,大衛,邁克任何幫助形成這個查詢將不勝感激。

再次感謝!

+2

請參閱[在數據庫列中存儲分隔列表真的很糟糕嗎?](http://stackoverflow.com/a/3653574) – eggyal

+0

Eek。如果你仍然可以控制你的數據庫結構,你應該讓作者成爲一個單獨的表,並帶有一個組合主鍵/一個外鍵。然後,例如,您將使用「從作者中選擇不同的authorName」。是的,我不確定MySQL可以分隔你的列表。一種編程語言可能能夠,但是......但即使它可以,我認爲你應該執行規則:1字段= 1值。 – Ariane

+0

數據來自第三方,所以很遺憾,我們與作者合併在一列中。 –

回答

1

可以得到結果集,但我真的只會這樣做,將其轉換爲另一個表,每個作者一行。我不想從應用程序代碼中運行這樣的查詢。可以使用SUBSTRING_INDEX函數來提取第一個,secpond等。列表中的作者,例如

SUBSTRING_INDEX(SUBSTRING_INDEX(authors,',', 1),',',-1) AS author1 
SUBSTRING_INDEX(SUBSTRING_INDEX(authors,',', 2),',',-1) AS author2 
SUBSTRING_INDEX(SUBSTRING_INDEX(authors,',', 3),',',-1) AS author3 

但是,最後這會變得混亂,因爲當您檢索超出列表的長度時,會得到最後一位作者。

所以,你可以算逗號的數字,一個相當難看的表情:

LENGTH(authors)-LENGTH(REPLACE(authors,',','')) AS count_commas 

但它只是作爲簡單的追加尾隨逗號,然後轉換成空字符串爲NULL 所以,更換作者用:

CONCAT(authors,',') 

然後把它包裹在TRIM和NULLIF函數中。

NULLIF(TRIM(foo),'') 

然後,您可以編寫一個查詢,從每行獲得第一作者,其他查詢,從每行得到第二作者(等同於第一個查詢,只是改變了「1」到「2 」,第三作者,等等,直到在一列值作者的最大數目將所有這些查詢連同UNION操作(這將消除重複操作。)

所以,這個查詢:

SELECT NULLIF(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(a.authors,','),',',1),',',-1)),'') AS author 
    FROM unfortunately_designed_table a 
UNION 
SELECT NULLIF(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(a.authors,','),',',2),',',-1)),'') 
    FROM unfortunately_designed_table a 
UNION 
SELECT NULLIF(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(a.authors,','),',',3),',',-1)),'') 
    FROM unfortunately_designed_table a 
UNION 
SELECT NULLIF(TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(a.authors,','),',',4),',',-1)),'') 
    FROM unfortunately_designed_table a 

這將返回唯一作者姓名的結果集(和無疑edly一個NULL)。這隻會得到列表中的前四名作者,您需要延長這些以獲得第五,第六等。

您可以通過查找最大逗號數來獲得該列中條目的最大數量,並加入1

SELECT MAX(LENGTH(a.authors)-LENGTH(REPLACE(a.authors,',','')))+1 AS max_count 
    FROM unfortunately_designed_table a 

,讓你知道你需要多遠擴展上面的查詢來獲取所有作者的值(在特定時間點運行查詢......沒有什麼可以阻止有人從另一個加作者在稍後時間列中的列表中。


在完成了在獨立行上獲取不同作者值的所有工作之後,您可能希望將它們留在這樣的列表中。與其合作更容易。

但是,當然,也可以將結果集轉換回逗號分隔列表,儘管返回的字符串的大小受到max_allowed_packet會話變量(iirc)的限制。

爲了將它作爲單行使用逗號分隔的列表從上面取出整個查詢,並將其作爲行視圖包裝在parens中,給它一個別名並使用GROUP_CONCAT函數。

SELECT GROUP_CONCAT(d.author ORDER BY d.author) AS distinct_authors 
    FROM (
     ... 
     ) d 
WHERE d.author IS NOT NULL 

如果你認爲所有這些表達式是醜陋的,而且應該是(從寫程序代碼除外)做到這一點,可惜的是一個簡單的方法,是不是真的有。關係數據庫被設計爲處理元組(行)中的信息,每行代表一個實體。將多個實體或值填充到單個列中違背了關係設計。因此,SQL不提供一種簡單的方法將字符串中的值提取到單獨的元組中,這就是爲什麼執行此操作的代碼非常混亂。

+0

謝謝斯賓塞,給它一個旋風。 –

相關問題