可以得到結果集,但我真的只會這樣做,將其轉換爲另一個表,每個作者一行。我不想從應用程序代碼中運行這樣的查詢。可以使用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不提供一種簡單的方法將字符串中的值提取到單獨的元組中,這就是爲什麼執行此操作的代碼非常混亂。
請參閱[在數據庫列中存儲分隔列表真的很糟糕嗎?](http://stackoverflow.com/a/3653574) – eggyal
Eek。如果你仍然可以控制你的數據庫結構,你應該讓作者成爲一個單獨的表,並帶有一個組合主鍵/一個外鍵。然後,例如,您將使用「從作者中選擇不同的authorName」。是的,我不確定MySQL可以分隔你的列表。一種編程語言可能能夠,但是......但即使它可以,我認爲你應該執行規則:1字段= 1值。 – Ariane
數據來自第三方,所以很遺憾,我們與作者合併在一列中。 –