有一个MySql数据库看起来像这样:
Id / name / hobby / province / created - int8
我想为每个省份只选择三条记录,但我不知道如何......
所以结果应该看起来像这样
[province1]
[1] blah bla
[2] blah blah
[3] blah blah
[province2]
[1] blah bla
[2] blah blah
[3] blah blah
等
感谢您的帮助。 最好的祝福。 微米。
答案 0 :(得分:1)
我不认为一个查询可以完成,除非您的数据库很小,因此您可以在脚本中进行进一步过滤。
答案 1 :(得分:1)
SELECT * FROM
(
SELECT t1.*, @num := IF(@t1 = province,@num+1,1) as num_in_group, @t1 := province
FROM table_name t1
INNER JOIN (SELECT @num:=0) num_table
ORDER BY province ASC, id desc
)xxx WHERE num_in_group <=3
这是非常直接且不是非常有效的方法,但从一开始可能会有所帮助。
<强>更新强>
SELECT * FROM
(
SELECT t1.*, @num := IF(@t1 = province,@num+1,1) as num_in_group, @t1 := province
FROM table_name t1
INNER JOIN (SELECT @num:=0) num_table
INNER JOIN (SELECT @t1 := NULL)x1
ORDER BY province ASC, id desc
)xxx WHERE num_in_group <=3
答案 2 :(得分:1)
在支持row_number()
的数据库中,“每组前N个”问题很容易,但MySQL并不是其中之一。据我所知,只有相当丑陋的解决方法。一种方法是group_concat
方式:
select yt.province
, lst.value
, substring_index(
substring_index(
group_concat(name separator ';'),
';',lst.value),
';',-1)
from YourTable yt
cross join
(
select 1 as value
union all select 2
union all select 3
) lst
group by
yt.Province
, lst.value;
如果每个省的名称少于三个,则会返回重复的行。你可以用另一个子查询排除那些。
另一种方法是变量方式,由Alex发布(我投票赞成)。格式略有不同:
select *
from (
SELECT name
, province
, @num := if(@lastprov = province,@num+1,1) as num_in_group
, @lastprov := province
from YourTable yt
order by
province
) as SubQueryAlias
JOIN (SELECT @num:=0, @lastprov:=null) as DeclareVariablesSubquery
WHERE num_in_group <= 3;
测试数据:
drop table if exists YourTable;
create table YourTable (id int, name varchar(25), province varchar(25));
insert YourTable values
(1,'Barack','New York'),
(2,'George W','New York'),
(3,'William','New York'),
(4,'George HW','New York'),
(5,'Ronald','Texas'),
(6,'James','Texas'),
(7,'Gerald','Texas'),
(8,'Richard','Texas'),
(9,'Lyndon','California'),
(10,'John','California'),
(11,'Dwight','Rhode Island'),
(12,'Harry','Wisconsin');
答案 3 :(得分:0)
这对MySQL不起作用(这就是为什么我将这个答案标记为社区维基),但是对于使用不同DBMS的人来说这很有趣并且绊倒了这个问题:
WITH TT (id, province, R) AS (
SELECT id, province, row_number() OVER(PARTITION BY province ORDER BY id DESC)
FROM your_table
GROUP BY id, province
)
SELECT id, province
FROM TT
WHERE R <= 3;