Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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查询以获取前N行数,但应基于列从每个组中至少包含一行_Sql_Sql Server_Tsql_Sql Server 2012 - Fatal编程技术网

SQL查询以获取前N行数,但应基于列从每个组中至少包含一行

SQL查询以获取前N行数,但应基于列从每个组中至少包含一行,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我有一个这样的SQL表 ID JobZone Title ------------------------------- 1 1 Job1 2 1 Job2 3 1 Job3 4 1 Job4 5 2 Job5 6

我有一个这样的SQL表

ID         JobZone        Title       
-------------------------------
1            1             Job1
2            1             Job2
3            1             Job3
4            1             Job4
5            2             Job5
6            2             Job6
7            2             Job7
8            2             Job8
9            3             Job9
10           3             Job10
11           4             Job11
12           4             Job12
13           5             Job13
14           4             Job14
15           5             Job15
16           6             Job16
17           7             Job17
18           7             Job18
19           7             Job19
20           8             Job20
ID         JobZone        Title       
-------------------------------
1            1             Job1
2            1             Job2
5            2             Job5
6            2             Job6
9            3             Job9
10           3             Job10
11           4             Job11
12           4             Job12
13           5             Job13
15           5             Job15
16           6             Job16
17           7             Job17
18           7             Job18
20           8             Job20
我需要从所有作业区中选择前2行。意味着如果每个作业区没有2行,则每个作业区至少应包含1行

我怎样才能做到这一点

我试过了

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY JobZone ORDER BY title) AS rn
   FROM mytable
)
SELECT *
FROM cte
WHERE rn = 1
此外,我还尝试了密集的排名,而不是行数,这也没有工作,因为我的预期

所以结果应该是这样的

ID         JobZone        Title       
-------------------------------
1            1             Job1
2            1             Job2
3            1             Job3
4            1             Job4
5            2             Job5
6            2             Job6
7            2             Job7
8            2             Job8
9            3             Job9
10           3             Job10
11           4             Job11
12           4             Job12
13           5             Job13
14           4             Job14
15           5             Job15
16           6             Job16
17           7             Job17
18           7             Job18
19           7             Job19
20           8             Job20
ID         JobZone        Title       
-------------------------------
1            1             Job1
2            1             Job2
5            2             Job5
6            2             Job6
9            3             Job9
10           3             Job10
11           4             Job11
12           4             Job12
13           5             Job13
15           5             Job15
16           6             Job16
17           7             Job17
18           7             Job18
20           8             Job20

如果您想要每个工作区的前2名,只需更改您的位置:

对于您的场景,您已经有了正确的行号。以下是三种常见选择的快速细分:

ROW_NUMBER-按顺序为分区内的每一行分配唯一的编号,子句{10,10,20}将ROW_NUMBER分配给{1,2,3} 秩-为每个唯一值分配唯一的数字,为具有相同值的行留下间隙,即:{10,10,20}将秩为{1,1,3} 稠密_秩-与秩相同,只是没有留下间隙{10,10,20}将_秩稠密到{1,1,2}
如果您想要每个工作区的前2名,只需更改您的位置:

对于您的场景,您已经有了正确的行号。以下是三种常见选择的快速细分:

ROW_NUMBER-按顺序为分区内的每一行分配唯一的编号,子句{10,10,20}将ROW_NUMBER分配给{1,2,3} 秩-为每个唯一值分配唯一的数字,为具有相同值的行留下间隙,即:{10,10,20}将秩为{1,1,3} 稠密_秩-与秩相同,只是没有留下间隙{10,10,20}将_秩稠密到{1,1,2}
它已经得到了回答,但我编写了一些代码来验证上面创建临时表的解决方案

CREATE TABLE #test
(
    ID int not null, 
    jobzone int not null, 
    title varchar(100) not null
)

INSERT INTO #test
SELECT 1, 1, 'Job1'
UNION
SELECT 2, 1, 'Job2'
UNION
SELECT 3, 1, 'Job3'
UNION
SELECT 4, 1, 'Job4'
UNION
SELECT 5, 2, 'Job5'
UNION
SELECT 6, 2, 'Job6'
UNION
SELECT 7, 2, 'Job7'
UNION
SELECT 8, 2, 'Job8'
UNION
SELECT 9, 3, 'Job9'
UNION
SELECT 10, 3, 'Job10'
UNION
SELECT 11, 4, 'Job11'
UNION
SELECT 12, 4, 'Job12'
UNION
SELECT 13, 5, 'Job13'
UNION
SELECT 14, 4, 'Job14'
UNION
SELECT 15, 5, 'Job15'
UNION
SELECT 16, 6, 'Job16'
UNION
SELECT 17, 7, 'Job17'
UNION
SELECT 18, 7, 'Job18'
UNION
SELECT 19, 7, 'Job19'
UNION
SELECT 20, 8, 'Job20'

select *
from #test

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY JobZone ORDER BY title) AS rn
   FROM #test
)
SELECT *
FROM cte
WHERE rn <= 2

它已经得到了回答,但我编写了一些代码来验证上面创建临时表的解决方案

CREATE TABLE #test
(
    ID int not null, 
    jobzone int not null, 
    title varchar(100) not null
)

INSERT INTO #test
SELECT 1, 1, 'Job1'
UNION
SELECT 2, 1, 'Job2'
UNION
SELECT 3, 1, 'Job3'
UNION
SELECT 4, 1, 'Job4'
UNION
SELECT 5, 2, 'Job5'
UNION
SELECT 6, 2, 'Job6'
UNION
SELECT 7, 2, 'Job7'
UNION
SELECT 8, 2, 'Job8'
UNION
SELECT 9, 3, 'Job9'
UNION
SELECT 10, 3, 'Job10'
UNION
SELECT 11, 4, 'Job11'
UNION
SELECT 12, 4, 'Job12'
UNION
SELECT 13, 5, 'Job13'
UNION
SELECT 14, 4, 'Job14'
UNION
SELECT 15, 5, 'Job15'
UNION
SELECT 16, 6, 'Job16'
UNION
SELECT 17, 7, 'Job17'
UNION
SELECT 18, 7, 'Job18'
UNION
SELECT 19, 7, 'Job19'
UNION
SELECT 20, 8, 'Job20'

select *
from #test

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY JobZone ORDER BY title) AS rn
   FROM #test
)
SELECT *
FROM cte
WHERE rn <= 2

请出示您的预期结果。我很难理解你想做什么。@Siyual我刚刚编辑了这个问题,以包含预期的结果。当然,你使用的是WHERE rn=1,似乎你想要WHERE rn无标准,只需按标题从每个区域的顶部排序即可。但是如果该区域下有2行以上,则应该有2行。如果N=2,并且有5个组,则返回5行?但是,如果N=10,并且有两个组,则返回最多5行作为组?如果一组太小,可能是2和8?请显示您的预期结果。我很难理解你想做什么。@Siyual我刚刚编辑了这个问题,以包含预期的结果。当然,你使用的是WHERE rn=1,似乎你想要WHERE rn无标准,只需按标题从每个区域的顶部排序即可。但是如果该区域下有2行以上,则应该有2行。如果N=2,并且有5个组,则返回5行?但是,如果N=10,并且有两个组,则返回最多5行作为组?如果一组太小,可能是2和8?