1、MySQL中group_concat函數
完整的語法如下:
group_concat([DISTINCT] 要連接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])
通俗點理解,其實是這樣的:group_concat()會計算哪些行屬於同一組,將屬於同一組的列顯示出來。要返回哪些列,由函數參數(就是字段名)決定。分組必須有個標準,就是根據group by指定的列進行分組。group_concat函數應該是在內部執行了group by語句。但是一定要要和group by語句配合使用。【測試】
select
t1.role_id,
t1.role_name,
group_concat(t3.menu_name separator '、') as power
from
tb_role_info t1
left join
tb_role_menu t2
on
t1.role_id = t2.role_id
left join
tb_menu_info t3
on
t2.menu_id = t3.menu_id
where
t1.delete_flag = '0' and
t2.delete_flag = '0' and
t3.delete_flag = '0'
group by
t1.role_id
表結構爲:
【tb_menu_info】
列名 | 物理名 | 類型 | 長度 | 不爲空 | 主鍵 | ||||||||||
菜單ID | menu_id | varchar | 20 | ○ | ○ | ||||||||||
菜單名稱 | menu_name | varchar | 100 | ||||||||||||
菜單URL | menu_url | varchar | 200 | ||||||||||||
順序 | serial_number | number | 4 |
【tb_role_menu】
列名 | 物理名 | 類型 | 長度 | 不爲空 | 主鍵 | ||||||||||
角色ID | role_id | varchar | 50 | ○ | ○ | ||||||||||
菜單ID | menu_id | varchar | 50 | ○ | ○ |
【tb_role_info】
列名 | 物理名 | 類型 | 長度 | 不爲空 | 主鍵 | ||||||||||
角色ID | role_id | varchar | 50 | ○ | ○ | ||||||||||
角色名稱 | role_name | varchar | 100 |
表內數據爲:
INSERT INTO `tb_role_info` VALUES ('ROLE0000000A', '超級管理員', '0', 0, '2015-5-26 19:13:13', 'sysadmin', '2015-5-26 19:13:22', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_menu_info` VALUES ('MENU0001', '部門管理', 'null', 1, '0', 0, '2015-5-26 19:15:42', 'sysadmin', '2015-5-26 19:15:49', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_menu_info` VALUES ('MENU0002', '角色管理', 'null', 1, '0', 0, '2015-5-26 19:15:42', 'sysadmin', '2015-5-26 19:15:49', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_menu_info` VALUES ('MENU0003', '賬號管理', 'null', 1, '0', 0, '2015-5-26 19:15:42', 'sysadmin', '2015-5-26 19:15:49', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_menu_info` VALUES ('MENU0004', '投票管理', 'null', 1, '0', 0, '2015-5-26 19:15:42', 'sysadmin', '2015-5-26 19:15:49', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_role_menu` VALUES ('ROLE0000000A', 'MENU0001', '0', 0, '2015-5-26 19:18:06', 'sysadmin', '2015-5-26 19:18:24', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_role_menu` VALUES ('ROLE0000000A', 'MENU0002', '0', 0, '2015-5-26 19:18:06', 'sysadmin', '2015-5-26 19:18:24', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_role_menu` VALUES ('ROLE0000000A', 'MENU0003', '0', 0, '2015-5-26 19:18:06', 'sysadmin', '2015-5-26 19:18:24', 'sysadmin', '0', 0, 0);
INSERT INTO `tb_role_menu` VALUES ('ROLE0000000A', 'MENU0004', '0', 0, '2015-5-26 19:18:06', 'sysadmin', '2015-5-26 19:18:24', 'sysadmin', '0', 0, 0);
查詢結果爲:
ROLE0000000A 超級管理員部門管理、角色管理、賬號管理、投票管理
2、一個投票系統選項的統計
業務需求:
1、一個一級問題中有很多二級問題(存放在一級問題表中)。
2、一個二級問題中有一部分是選擇題部分(二級問題存放在二級問題表中)。
3、所有二級問題中選擇題部分的所有選項信息存儲在選項表中。
4、在投票過程中,對於一個選項,有人選取一次,則將其在結果表中記錄一次,並記錄是誰選擇的。如果一個選項,始終沒有人去選擇,則不出現在結果表中。
5、也就是說,一級問題的字表爲二級問題,二級問題的字表爲選項表,選項表的字表爲結果表。
6、現在要統計每一個二級問題(選擇體型的)的每一個選項有多少人去選擇它並算出比例。
7、這就需要在sql中統計兩個結果。
8、第一個結果:每一個二級問題一共有多少人去選擇。
9、第二個結果:每一個二級問題的每一個選項有多少人去選擇。
表結構如下:
sql語句如下:
第一個結果
select
main_question_id,
chr_question_id,
option_id,
result_id,
option_content,
option_pic_url,
is_selected,
subjective_content,
voter_id,
voter_name,
voter_ip,
serial_number
from
tb_question_result_info
where
delete_flag = '0' and
main_question_id = #mainQuestionId#
order by
serial_number asc
第二個結果
方案一:
select
count(B.result_id) as allOptionCount,
A.main_question_id,
A.chr_question_id,
A.chr_question_name,
A.chr_question_type_flag,
A.chr_answer_type_flag
from
tb_chr_question_info A
LEFT JOIN
tb_question_result_info B
ON
A.main_question_id = B.main_question_id AND
A.chr_question_id = B.chr_question_id
WHERE
A.delete_flag = '0' AND
A.main_question_id = #mainQuestionId#
GROUP BY
A.chr_question_id
order by
A.serial_number asc
方案二:
select
(
select
count(1)
from
tb_question_result_info
where
main_question_id = B.main_question_id and
chr_question_id = B.chr_question_id and
option_id =B.option_id
),
B.main_question_id,
B.chr_question_id,
B.option_id,
B.option_content
from
tb_option_info B
where
B.delete_flag = '0' AND
B.main_question_id = '50095982-07f9-4811-8262-6bf5d07c1c16'
order by
B.serial_number asc
sql理解:先忽略括號裏面的查詢,假設除了括號部分查詢完畢。 然後根據查完數據每一行的條件去進行子查詢。