2012-04-03 156 views
2

我有一個數據庫在'用戶'表中包含4個字段ID,名稱,性別,語言
前。 (數據庫條目)簡單的數據庫查詢爲mysql

1 jhon  male  en-sp-gr 
2 mira female sp- 
3 mike  male  en- 
4 shel female sp-gr 

等等

這裏EN,SP,GR是語言英語,西班牙語,德語我試圖獲取計數誰說話只帶用戶 , SP(英語和西班牙語)的數據庫包含超過300個用戶,我更更困惑如何讓誰講桌上的唯一SP語言外地用戶的數量包含字符串

en-sp-gr 

我怎麼能忽略-gr和連字符(-)形成的字符串,這只是一行,我必須執行此的每一行,然後只算誰講的連接和SP的用戶。 我不是專家在SQL :(

+0

是你的數據庫中的語言一致的順序? – 2012-04-03 18:34:06

+0

我想你不能重構數據庫來使用外鍵? – 2012-04-03 18:35:09

+0

@davide不,它可能是隨機的 sp-en,en-,sp-,gr- – smita 2012-04-03 18:45:16

回答

2

這就是爲什麼你不應該在一個字段中存儲多個值。它們應該存儲在規範化的表中。

但是,您可以通過將-替換爲,並使用FIND_IN_SET()來完成此操作。這是必要的,因爲FIND_IN_SET()需要用逗號分隔的值列表。儘管這隻能用少數幾種語言進行合理管理,因爲您需要將所有排列編碼到查詢中。出於這個原因(其中包括索引),強烈建議將其重構成將用戶鏈接到他們的口語的相關表格。

SELECT COUNT(*) FROM users 
WHERE 
    FIND_IN_SET('en', REPLACE(language,'-',',')) > 0 
    AND FIND_IN_SET('sp', REPLACE(language,'-',',')) > 0 
    AND FIND_IN_SET('gr', REPLACE(language,'-',',')) = 0 
+0

我不知道這個功能。好的! :) – 2012-04-03 18:37:01

+0

@jperovic我在SO這裏學到了它,在其他巨人的肩膀上。 – 2012-04-03 18:37:41

+0

這不會限制它的外觀,儘管 – 2012-04-03 18:38:18

2

你可以做這樣的事情:

SELECT * 
FROM users 
WHERE language IN ('en-sp', 'sp-en') 

但是,你真的應該看看規範化數據庫:

Users 
ID|Name|Gender 

Languages 
ID|Code 

User_Language_Map 
UserID|LanguageID 

那麼你可以做什麼像這樣:

SELECT * 
FROM Users 
WHERE ID IN 
(
    SELECT UserID 
    FROM User_Language_Map 
    WHERE LanguageID IN (IDFORSP, IDFORGR) 
    GROUP BY UserID 
    HAVING COUNT(DISTINCT LanguageID) = 2 
) 

如果你不能這樣做,並且語言過濾器將是動態的,那麼你真的需要創建一個函數來創建適當的字符串組合(或者你可以動態構建一個正則表達式)並將其傳遞給你的IN。否則,我不知道你有很多選擇,因爲你在這個時候正在解析字符串。

+0

但我不能編輯數據庫,我只能獲取記錄 – smita 2012-04-03 18:47:05

+0

@smita更新我的答案在最後給你如何這可能不僅僅是en-sp更可能。它不會是很漂亮的方式。當你開始存儲應該是關係的字符串時,會發生什麼 – 2012-04-03 18:53:42

0
SELECT 
     count(case when language = 'en' then language end) as English, 
     count(case when language = 'sp' then language end) as Spanish 
FROM users 

在上面的查詢可以指望的英語用戶和西班牙語Laguage 用戶。