此代码有效。
因为您可能会有重复,并且您只需要为每个用户/月份组合提供一个答案,所以我们必须通过解决方案获得更高级的解决方案。
该解决方案首先根据我们关心的每个组合(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