2016-08-23 125 views
1

我嘗試做以下,但我不能設法得到它的權利尚未:(MySql的拆分查詢組百分比

我有這些表:

table1 -> tb1_id, tb1_name 

Sample Data: 
-------------- 
1 group1 
2 group2 
3 group3 
4 group4 
5 group5 

table2 -> tb2_id, tb2_sector, tb2_tb3_id 

Sample Data: 
-------------- 
1 alpha 1 
2 beta 2 
3 gamma 2 
4 delta 2 
5 epsilon 4 

table3 -> tb3_id, tb3_mid, tb3_section 

Sample Data: 
-------------- 
1 234 alpha,beta,gama,delta 

這是我的輸出尋找:

Name Count  % 
------ ----- ----- 
group1 1  25% 
group2 3  75% 
group3 0  0% 
group4 0  0% 
group5 0  0% 

基本上,我需要一個分裂用逗號(表3中tb3_section),然後分隔列值找到合適的組爲每個值(表2給我組ID與table1的鏈接),然後按組計算總數並得出百分比(假設總數爲100%)。

這是我試過到目前爲止查詢:

我搜索了分裂值樣本,發現一個首先創建一個數字表幹分:

create table numbers (
    `n` INT(11) SIGNED 
    , PRIMARY KEY(`n`) 
) 

INSERT INTO numbers(n) SELECT @row := @row + 1 FROM 
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t, 
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2, 
(SELECT 0 UNION ALL SELECT 1) t8, 
(SELECT @row:=0) ti; 

之後,我這樣做:

select tb3_section, count(1) from ( 
    select 
    tb3_mid, 
    substring_index(
     substring_index(tb3_section, ',', n), 
     ',', 
     -1 
    ) as tb3_section from table3 
    join numbers 
    on char_length(tb3_section) 
     - char_length(replace(tb3_section, ',', '')) 
     >= n - 1 
) tb3_section_dashboard 
group by 1 

這不給我組數。只是做了tb3_section的分割,但沒有給我正確的計數和相應的百分比。任何想法都會非常感謝,非常感謝。

最新的更新

首先,我想感謝@eggyal指着我正確的方向和@Shadow的鄙視知道,我沒有服用最好的方法,他想出了一個快速修復我的問題。我設法改變了方法,並從table3中刪除了逗號分隔的值。相反,現在我爲每個新值添加多行(並添加了一個約束以避免重複)。

現在表3樣子:

Sample Data: 
-------------- 
1 234 alpha 
2 234 beta 
3 234 gama 
4 234 delta 
5 235 alpha 

這是我從@shadow樣品時的查詢:使用

SELECT t1.tb1_name, COUNT(t3.tb3_section) AS no_per_group, 
COUNT(t3.tb3_section)/t4.no_of_groups AS percentage 
FROM t1 left 
JOIN t2 ON t1.tb1_id=t2.tb2_tb3_id 
INNER JOIN t3 ON t2.tb2_sector=t3.tb3_section>0 
JOIN (SELECT COUNT(*) AS no_of_groups 
     FROM t3 INNER JOIN t2 ON t2.tb2_sector=t3.tb3_section>0) t4 
GROUP BY t1.tb1_name 

而不是FIND_IN_SET現在我用=到匹配確切的值。 現在我得到的東西像下面,但比例看起來很奇怪,我懷念那個沒有匹配一組:

Name  no_per_group  percentage 
-----  ------------- ---------- 
group1  2    0.1053 
group3  3    0.1579 
group4  3    0.1579 
group5  3    0.1579 

雖然我仍然需要這樣的東西:

Name Count  % 
------ ----- ----- 
group1 1  25% 
group2 3  75% 
group3 0  0% 
group4 0  0% 
group5 0  0% 

注意,如果在一組中沒有匹配,我仍然需要顯示該組。 因爲我有成千上萬的記錄彼此不同,我需要添加另一個條件:其中tb3_mid = 234。喜歡這一點,結果正在使用tb3_mid。

+2

你可能有興趣閱讀[@Bill Karwin(https://stackoverflow.com/users/20860/bill-karwin)的回答[在數據庫列中存儲分隔列表真的不好嗎?](http://stackoverflow.com/a/3653574) – eggyal

+0

非常感謝@eggyal指出法案的偉大答案。在我的情況下,問題是我沒有完全控制實際的表,因爲我沒有創建它們:(但是,我現在可以體驗到在一列中存儲分隔值的問題 – carol1287

+0

您可以構造一個連接謂詞來自MySQL的['FIND_IN_SET()'](https://dev.mysql.com/doc/en/string-functions.html#function_find-in-set)函數。 – eggyal

回答

2

最好的解決方案是重新設計您的表格結構並將分隔值列表中的數據移動到單獨的表格中。

快速解決方案是利用MySQL的find_in_set()函數。

要獲得總條目數的消息表(表3):

select count(*) as no_of_groups 
from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0 

每組獲得的計數,加按組名加入到表1和組。爲了計算比例,添加上述查詢作爲子查詢:

select t1.tb1_name, count(t3.tb3_section) as no_per_group, count(t3.tb3_section)/t4.no_of_groups as percentage 
from t1 left join t2 on t1.tb1_id=t2.tb2_tb3_id 
inner join t3 on find_in_set(t2.tb2_sector,t3.tb3_section)>0 
join (select count(*) as no_of_groups 
     from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0) t4 --no join condition makes a Cartesian join 
group by t1.tb1_name 
+0

非常感謝Shadow花時間來幫助我你的查詢解決了原來的問題,我設法說服了我的同事改變了我帶你的表格結構和@eggyal的建議並修改了結構,現在我會更新我的問題,現在我得到了幾乎所有的結果我希望有一個例外,當沒有匹配時,我不會得到0%,但我認爲必須是左連接在某處丟失。 – carol1287