可以使用临时表逐步解决:
-- get counts for each user and option
DROP TEMPORARY TABLE IF EXISTS tmp_selected_options;
CREATE TEMPORARY TABLE tmp_selected_options
SELECT a.user_id, a.option_id, COUNT(a.option_id) AS numSelected
FROM answer a
GROUP BY a.user_id, a.option_id
;
select * from tmp_selected_options;
-- get the max number an option was selected for each user
DROP TEMPORARY TABLE IF EXISTS tmp_max_selected;
CREATE TEMPORARY TABLE tmp_max_selected
SELECT so.user_id, MAX(so.numSelected) AS maxSelected
FROM tmp_selected_options so
GROUP BY so.user_id
;
select * from tmp_max_selected;
-- get otions that were selected most for each user
DROP TEMPORARY TABLE IF EXISTS tmp_most_selected_otions;
CREATE TEMPORARY TABLE tmp_most_selected_otions
SELECT so.user_id, so.option_id
FROM tmp_max_selected ms
JOIN tmp_selected_options so
ON so.user_id = ms.user_id
AND so.numSelected = ms.maxSelected
;
select * from tmp_most_selected_otions;
-- get least option-id of most selected options for each user
SELECT u.id AS user_id, MIN(mso.option_id) AS option_id
FROM user u
LEFT JOIN tmp_most_selected_otions mso ON mso.user_id = u.id
GROUP BY u.id
;
Notes:
- 您可能需要添加一些键以提高性能。
- 如果用户选择两个选项的次数相同,则将选择 ID 最少的选项。
将最后一个语句中的临时表替换为相应的选择,您将得到以下查询:
-- get least option-id of most selected options for each user
SELECT u.id AS user_id, MIN(mso.option_id) AS option_id
FROM user u
LEFT JOIN ( -- get otions that were selected most for each user
SELECT so.user_id, so.option_id
FROM ( -- get the max number an option was selected for each user
SELECT so.user_id, MAX(so.numSelected) AS maxSelected
FROM ( -- get counts for each user and option
SELECT a.user_id, a.option_id, COUNT(a.option_id) AS numSelected
FROM answer a
GROUP BY a.user_id, a.option_id
) so
GROUP BY so.user_id
) ms
JOIN ( -- get for counts each user and option
SELECT a.user_id, a.option_id, COUNT(a.option_id) AS numSelected
FROM answer a
GROUP BY a.user_id, a.option_id
) so
ON so.user_id = ms.user_id
AND so.numSelected = ms.maxSelected
) mso ON mso.user_id = u.id
GROUP BY u.id
http://sqlfiddle.com/#!9/c2b20/2 http://sqlfiddle.com/#!9/c2b20/2