此代碼有效。
因爲您可能會有重複,並且您只需要爲每個用戶/月份組合提供一個答案,所以我們必須通過解決方案獲得更高級的解決方案。
該解決方案首先根據我們關心的每個組合(aggregated_picked_colors子查詢)有多少行進行聚合,然後爲每個我們關心的組合(sorted_picked_colors子查詢)分配顏色數量的排名。頂級查詢然後只是從ranking_picked_colors中提取排名最高的解決方案。
上增加這些排名列計數器的方法的更多細節,請訪問:ROW_NUMBER() in MySQL
/*
create table picked_colors (
color varchar(10),
name varchar(10),
month tinyint
);
insert into picked_colors (color, name, month) values ('Yellow', 'Tom', 4);
insert into picked_colors (color, name, month) values ('Red', 'Tom', 4);
insert into picked_colors (color, name, month) values ('Yellow', 'Tom', 4);
insert into picked_colors (color, name, month) values ('Blue', 'Tom', 3);
insert into picked_colors (color, name, month) values ('Red', 'Sam', 4);
insert into picked_colors (color, name, month) values ('Pink', 'Sam', 4);
insert into picked_colors (color, name, month) values ('Pink', 'Sam', 4);
insert into picked_colors (color, name, month) values ('Yellow', 'Sam', 3);
*/
select
name, month, color
from
(
select
@row_num := IF(@prev_value=concat_ws('', name, month),@row_num+1,1) as row_number,
color, name, month, row_count,
@prev_value := concat_ws('', name, month) as prev_value
from
(
select
name, month, color, count(*) as row_count
from
picked_colors
group by
name, month, color
) aggregated_picked_colors,
(select @row_num := 1) x,
(select @prev_value := '') y
order by
name, month, row_count desc
) ranked_picked_colors
where
row_number = 1
order by
name, month desc
返回:
+------+-------+--------+
| name | month | color |
+------+-------+--------+
| Sam | 4 | Pink |
| Sam | 3 | Yellow |
| Tom | 4 | Yellow |
| Tom | 3 | Blue |
+------+-------+--------+
編輯:添加說明/演練
的這裏的主要目標是我們想要獲取每組數據t我們正在彙總的帽子(在這種情況下,是每個名稱/月份的組合),並根據它們的行數對顏色進行排序。然後,我們要插入一個新列到這些結果與明確的排名,將顏色擁有最行,其顏色有下一個最行等
當我們開始,我們不是真的準備好排列這些事情,我們有多行說「黃色」,但我們希望數據顯示「黃色有5行」或沿着這些行。因此,我們寫的第一個查詢做這種聚合:
select
name, month, color, count(*) as row_count
from
picked_colors
group by
name, month, color;
這將返回:
+------+-------+--------+-----------+
| name | month | color | row_count |
+------+-------+--------+-----------+
| Sam | 3 | Yellow | 1 |
| Sam | 4 | Pink | 2 |
| Sam | 4 | Red | 1 |
| Tom | 3 | Blue | 1 |
| Tom | 4 | Red | 1 |
| Tom | 4 | Yellow | 2 |
+------+-------+--------+-----------+
這說明,每個名稱和月,每個顏色多少行了。
接下來,我們要證明,對於每個名稱和月,其顏色有最行,其顏色有第二個最行等,這邏輯是最令人費解。
的這裏的想法是,在表定義,我們插入這些行:
(select @row_num := 1) x,
(select @prev_value := '') y
這些命令基本上初始化這些變量。只提供X和Y名稱是因爲我們必須給這些「子查詢」一個名稱,它們實際上並未在任何地方使用。
內的查詢,我們使用這些變量。實際上,他們檢查顏色/名稱組合是否從前一行更改過。如果它們改變了,那麼我們將@row_num設置爲1,如果它們沒有改變,那麼我們就增加它。我們必須小心地按照與我們比較相鄰行相同的標準對此查詢進行排序;改變排序順序會破壞邏輯。
select
@row_num := IF(@prev_value=concat_ws('', name, month),@row_num+1,1) as row_number,
color, name, month, row_count,
@prev_value := concat_ws('', name, month) as prev_value
from
(
select
name, month, color, count(*) as row_count
from
picked_colors
group by
name, month, color
) aggregated_picked_colors,
(select @row_num := 1) x,
(select @prev_value := '') y
order by
name, month, row_count desc;
這將返回:
+------------+--------+------+-------+-----------+------------+
| row_number | color | name | month | row_count | prev_value |
+------------+--------+------+-------+-----------+------------+
| 1 | Yellow | Sam | 3 | 1 | Sam3 |
| 1 | Pink | Sam | 4 | 2 | Sam4 |
| 2 | Red | Sam | 4 | 1 | Sam4 |
| 1 | Blue | Tom | 3 | 1 | Tom3 |
| 1 | Yellow | Tom | 4 | 2 | Tom4 |
| 2 | Red | Tom | 4 | 1 | Tom4 |
+------------+--------+------+-------+-----------+------------+
這裏,我們可以忽略「prev_value」專欄中,我們實際上並不希望這些結果,我們只是設定要使用這個變量,當我們考察下一行。重要的是看看我們有相同的名稱和月份,row_count最高的顏色row_number = 1,row_count次高的顏色row_number = 2等。
最後一步是查詢只需要我們想要的字段,以及row_number = 1的行。這些行對應於每個名稱/月份組合的最高頻率顏色。
select
name, month, color
from
(
select
@row_num := IF(@prev_value=concat_ws('', name, month),@row_num+1,1) as row_number,
color, name, month, row_count,
@prev_value := concat_ws('', name, month) as prev_value
from
(
select
name, month, color, count(*) as row_count
from
picked_colors
group by
name, month, color
) aggregated_picked_colors,
(select @row_num := 1) x,
(select @prev_value := '') y
order by
name, month, row_count desc
) ranked_picked_colors
where
row_number = 1
order by
name, month desc
這將返回:
+------+-------+--------+
| name | month | color |
+------+-------+--------+
| Sam | 4 | Pink |
| Sam | 3 | Yellow |
| Tom | 4 | Yellow |
| Tom | 3 | Blue |
+------+-------+--------+
向我們展示了 「很多東西」,你試過。我們需要知道您目前如何嘗試解決這個問題,因爲您很可能已經擁有大部分解決方案。 – user2366842
如果最喜歡的項目有領帶,你想要什麼樣的結果? –
@ user2366842我試圖讓它更清楚。你可以嗎? – Cyril