假设我有一个包含4列的表:
Col1 Col2 Col3 Col4
我的初步查询是:
SELECT Col1, Col2, Col3, Col4
FROM myTable
ORDER BY Col1, Col2, Col3 DESC, Col4
我想要的结果是所有4列,但是在这个条件下,当Col1,Col2相等时,Top N Col3不同的行。
N = 2的示例:
表格样本数据:
Col1 Col2 Col3 Col4
---------------------
1 a 2000 s
1 a 2002 c
1 a 2001 b
2 b 1998 s
2 b 2002 c
2 b 2000 b
3 c 2000 b
1 f 1998 n
1 g 1999 e
期望的结果:
1 a 2002 c
1 a 2001 b
1 f 1998 n
1 g 1999 e
2 b 2002 c
2 b 2000 b
3 c 2000 b
在另一个描述中,当(col1, col2)
在多个记录中重复时,只需在按Col3降序排序时导出这些记录的前N行。
我可以使用SQL脚本执行此操作,无需硬编码吗?
declare @t table (Col1 int, Col2 char, Col3 int, Col4 char);
insert into @t values
(1, 'a', 2000, 's'),
(1, 'a', 2002, 'c'),
(1, 'a', 2001, 'b'),
(2, 'b', 1998, 's'),
(2, 'b', 2002, 'c'),
(2, 'b', 2000, 'b'),
(3, 'c', 2000, 'b'),
(1, 'f', 1998, 'n'),
(1, 'g', 1999, 'e');
declare @N int = 2; -- number per "top"
with cte as
(
select *,
row_number() over(partition by col1, col2 order by col3 desc) as rn
from @t
)
select *
from cte c
where rn <= @N;
我认为下面的代码是预期的
declare @tab table (Col1 int, Col2 char(1), Col3 int, Col4 char(1))
declare @N int
insert into @tab
select 1, 'a' , 2000, 's'
union all
select 1 , 'a' , 2002 , 'c'
union all
select 1 , 'a' , 2001 , 'b'
union all
select 2 , 'b' , 1998 , 's'
union all
select 2 , 'b' , 2002 ,'c'
union all
select 2 , 'b' , 2000 ,'b'
union all
select 3 , 'c' , 2000 ,'b'
union all
select 1 , 'f' , 1998 ,'n'
union all
select 1 , 'g' , 1999 ,'e'
;with tab as
(
select ROW_NUMBER() over(partition by t.col1,t.col2 order by t.col3 desc) as row,t.*
from @tab t
)
select Col1,Col2,Col3,Col4
from tab
where row < 3
产量
Col1 Col2 Col3 Col4
1 a 2002 c
1 a 2001 b
1 f 1998 n
1 g 1999 e
2 b 2002 c
2 b 2000 b
3 c 2000 b
方法1- FOR MSSQL
http://sqlfiddle.com/#!6/4bda39/6
with a as (
select ROW_NUMBER() over(partition by t.col1,t.col2 order by t.col3 desc) as row,t.*
from myTable as t)
select * from a where a.row <= 2
替换a.row <= 2(2与您的N)
方法2-用于MYSQL
http://sqlfiddle.com/#!9/79e81a/63
SELECT myTable.Col1, myTable.Col2, myTable.Col3, myTable.Col4
FROM (
Select Col1 as Col1, Col2 as Col2, count(Col1) as cc, AVG(Col3) as aa
From myTable
group by Col1, Col2) as tt
join myTable on myTable.Col1 = tt.Col1 and myTable.Col2 = tt.Col2
where myTable.Col3 >= tt.aa
Order by Col1 ,Col2 ,Col3 Desc,Col4
方法3-用于MYSQL
http://sqlfiddle.com/#!9/79e81a/79
SELECT * FROM (
SELECT CASE Col1
WHEN @Col1 THEN
CASE Col2
WHEN @Col2 THEN @curRow := @curRow + 1
ELSE @curRow := 1
END
ELSE @curRow :=1
END AS rank,
@Col1 := Col1 AS Col1,
@Col2 := Col2 AS Col2,
Col3, Col4
FROM myTable p
JOIN (SELECT @curRow := 0, @Col1 := 0, @Col2 := '') r
ORDER BY Col1, Col2, Col3 DESC) as tt
WHERE tt.rank <= 2
替换tt.rank <= 2将索引替换为2