Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL Server中具有4列的表中的每个集合中获取前N行_Sql_Sql Server - Fatal编程技术网

从SQL Server中具有4列的表中的每个集合中获取前N行

从SQL Server中具有4列的表中的每个集合中获取前N行,sql,sql-server,Sql,Sql Server,假设我有一个包含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

假设我有一个包含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脚本而不进行硬编码吗?

方法1-用于MSSQL

方法3-用于MYSQL


替换tt.rank我认为下面的代码和预期的一样

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

对列使用group by子句,然后使用order by col3 desc获得所需的output4列,而不是字段。在我的问题中,SQL中的group by不适用,因为字段具有不同的值,当按列分组时,每个值都会转到自己的组,并且无法访问Top N col3@jarlh:ThanksThanks但Max返回Top Col3值但我希望按Col3排序时组的N个记录,示例中描述的是ThanksThanks,但条件是:当在多个具有Col1、Col2相等的记录中时,只导出该记录的Top N记录,该记录按Col3的降序排序,对不起,清楚吗?或者我必须描述更多?请注意这个问题,当Col1,Col2在多行中重复时,我的期望结果是Top N记录,COL3的顺序现在略有变化感谢您详细且经过测试的答案,这是非常好的答案
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 
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
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
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;