2012-05-24 70 views
3

我有以下的用戶數據庫,每個用戶可以在不同的級別上講不同的語言。統計整套數據庫中唯一元素的數量

id  langs 
12  EN-21 
36  EN-2,RU-3 
41  EN-9 
57  DE-35,EN-28 
60  DE-9,RU-14 

我想創建MySQL查詢計數每一種語言的出現無論的水平。 所需的選項卡應該是這樣的:

lang count 
EN  4 
DE  2 
RU  2 

我已經嘗試過的這種不同的組合,但它完美的遠。

SELECT 
    DISTINCT SUBSTRING_INDEX(langs, '-', 1) AS lang, 
-- COUNT(langs) as count 
-- SUM(
--  (SELECT DISTINCT SUBSTRING_INDEX(langs, '-', 1) 
--  FROM people 
--  WHERE langs != '') 
-- ) 
FROM people 
WHERE langs != '' 
-- GROUP BY lang 
ORDER BY lang 
+0

應重新組織表'people' – triclosan

+0

是語言固定值的計數?我在這裏只看到3 – triclosan

+2

如果我有另一行爲'EN-32,EN-45'那麼如果計算EN會是5還是6? –

回答

0
SELECT SUBSTRING_INDEX(langs, '-', 1) AS lang, count(1) as count_lang 
FROM people 
WHERE langs!='' 
GROUP BY lang 
ORDER BY lang 

請試試這個,讓我知道你會得到什麼。

+1

你可以嘗試一下:http://www.sqlfiddle.com/#!2/8aae3/3。我相信問題不在於計數。這是因爲'RU'只出現在二級或更低級別而缺少'RU'。 – mellamokb

2

如果該集合中的語言數量有最大限制,則可以拉出所有的第一個元素,第二個元素,第三個元素等,並將它們合併在一起。下面是從語言集翻出任何第一或第二個元素,並將它們結合的例子:

select distinct substring_index(langs, '-', 1) as lang 
from people where langs != '' 
union 
select distinct SUBSTRING_INDEX(SUBSTRING_INDEX(langs, '-', 2), ',', -1) 
from people where LENGTH(langs) - LENGTH(REPLACE(langs,',','')) + 1 > 1 

演示:http://www.sqlfiddle.com/#!2/b86f2/1


從那裏,它的語言列表與列表相結合的問題人們和計數匹配的數量,例如通過對比people.langs like '%EN%'

select 
    lang, 
    count(case when people.langs like concat('%',langs.lang,'%') then 1 end) as count 
from people, 
    (
    select distinct substring_index(langs, '-', 1) as lang 
    from people where langs != '' 
    union 
    select distinct SUBSTRING_INDEX(SUBSTRING_INDEX(langs, '-', 2), ',', -1) 
    from people where LENGTH(langs) - LENGTH(REPLACE(langs,',','')) + 1 > 1 
) langs 
group by langs.lang 
order by langs.lang 

輸出示例:

LANG COUNT 
==== ==== 
DE  2 
EN  4 
RU  2 

演示:http://www.sqlfiddle.com/#!2/b86f2/5

+0

這真是太好了,但正如我在上面的評論中所寫的那樣,用戶的語言數量在理論上是無限的。 好吧,似乎我必須堅持使用PHP構建結果表的原始計劃。很遺憾,MySQL在PHP中沒有像explode()這樣的東西。 – meridius

+0

Ya,MySQL(和其他數據庫引擎)在字符串處理方面通常不夠強大。我會同意你最好的選擇是用PHP來處理。 – mellamokb