如何在分区依据 sql 中使用别名
How to use alias name with partition by in sql
我正在获取被归类为高尔夫差点的球员的记录。就像让分在 0 到 5 之间的球员在 0-5 范围内,同样让分在 6-11 之间在 6-11 范围内,依此类推。我正在尝试的是从每个范围中获取前 3 名玩家,以便我可以为每一轮设置航班。
我使用 partition by 子句来分隔记录,并使用 ROW_NUMBER 从每个范围中获得前 3 名玩家。为了定义范围,我使用了多种情况。现在我如何使用范围作为别名与分区依据或任何可以生成正确结果的方式。以下是我的查询。
select * from (
select uu.Id, firstname, lastname, userhandicap,
case when userhandicap>=0 and userhandicap<=5 then '0-5'
when userhandicap>=6 and userhandicap<=11 then '6-11'
when UserHandicap>=12 and UserHandicap<=18 then '12-18'
when UserHandicap>=19 and UserHandicap<=26 then '19-26'
else '27 and above' end as range, RN = ROW_Number() over (PARTITION BY
range order by cast(userhandicap as int))
from dbo.[User] uu inner join dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId
where eru.UserId not in (Select fp.UserId from dbo.[FlightPlayer] fp
inner join dbo.[Flight] f
on fp.FlightId = f.Id
where f.Rounds = '1'
and f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and f.EventId =
'7de10ad6-098d-419f-9c2d-2e62803ad1f7')
and eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7') uu
WHERE
uu.RN <= 3
使用 cte
with cte as
(
select uu.Id, firstname, lastname, userhandicap,
case when userhandicap>=0 and userhandicap<=5 then '0-5'
when userhandicap>=6 and userhandicap<=11 then '6-11'
when UserHandicap>=12 and UserHandicap<=18 then '12-18'
when UserHandicap>=19 and UserHandicap<=26 then '19-26'
else '27 and above' end as range
from dbo.[User] uu inner join dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId
where eru.UserId not in (Select fp.UserId from dbo.[FlightPlayer] fp
inner join dbo.[Flight] f
on fp.FlightId = f.Id
where f.Rounds = '1'
and f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and f.EventId =
'7de10ad6-098d-419f-9c2d-2e62803ad1f7')
and eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
), t2 as
(
select *,row_number() over(partition by range order by cast(userhandicap as int) rn from cte
) select * from t2 where rn<=3
您可以使用 apply
在 子查询中定义 range
值 。这是定义范围的最简单方法:
select *
from (select uu.Id, firstname, lastname, userhandicap,
row_number() over (partition by v.range order by cast(userhandicap as int)) as seqnum
from dbo.[User] uu inner join
dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId cross apply
(values (case when userhandicap <= 5 then '0-5'
when userhandicap <= 11 then '6-11'
when UserHandicap <= 18 then '12-18'
when UserHandicap <= 26 then '19-26'
else '27 and above'
end)
) v(range)
where not exists (select 1
from dbo.[FlightPlayer] fp join
dbo.[Flight] f
on fp.FlightId = f.Id
where eru.UserId = fp.UserId and
f.Rounds = '1' and
f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and
f.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
) and
eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
) uu
where uu.seqnum <= 3;
注意查询的其他更改:
- 不要将
not in
与子查询一起使用。如果子查询returns一个NULL
值,那么所有值都被过滤掉。这不是(通常)预期的行为。
case
表达式过于复杂。使用 case
保证按顺序评估条件的事实。
- 您应该在具有多个查询的查询中限定 所有 列名称。但是,不清楚这些列的来源。
- 根据您最初的逻辑(和高尔夫规则),大概
handicap
永远不会是负数,所以我很乐意删除该条件。
我正在获取被归类为高尔夫差点的球员的记录。就像让分在 0 到 5 之间的球员在 0-5 范围内,同样让分在 6-11 之间在 6-11 范围内,依此类推。我正在尝试的是从每个范围中获取前 3 名玩家,以便我可以为每一轮设置航班。
我使用 partition by 子句来分隔记录,并使用 ROW_NUMBER 从每个范围中获得前 3 名玩家。为了定义范围,我使用了多种情况。现在我如何使用范围作为别名与分区依据或任何可以生成正确结果的方式。以下是我的查询。
select * from (
select uu.Id, firstname, lastname, userhandicap,
case when userhandicap>=0 and userhandicap<=5 then '0-5'
when userhandicap>=6 and userhandicap<=11 then '6-11'
when UserHandicap>=12 and UserHandicap<=18 then '12-18'
when UserHandicap>=19 and UserHandicap<=26 then '19-26'
else '27 and above' end as range, RN = ROW_Number() over (PARTITION BY
range order by cast(userhandicap as int))
from dbo.[User] uu inner join dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId
where eru.UserId not in (Select fp.UserId from dbo.[FlightPlayer] fp
inner join dbo.[Flight] f
on fp.FlightId = f.Id
where f.Rounds = '1'
and f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and f.EventId =
'7de10ad6-098d-419f-9c2d-2e62803ad1f7')
and eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7') uu
WHERE
uu.RN <= 3
使用 cte
with cte as
(
select uu.Id, firstname, lastname, userhandicap,
case when userhandicap>=0 and userhandicap<=5 then '0-5'
when userhandicap>=6 and userhandicap<=11 then '6-11'
when UserHandicap>=12 and UserHandicap<=18 then '12-18'
when UserHandicap>=19 and UserHandicap<=26 then '19-26'
else '27 and above' end as range
from dbo.[User] uu inner join dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId
where eru.UserId not in (Select fp.UserId from dbo.[FlightPlayer] fp
inner join dbo.[Flight] f
on fp.FlightId = f.Id
where f.Rounds = '1'
and f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and f.EventId =
'7de10ad6-098d-419f-9c2d-2e62803ad1f7')
and eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
), t2 as
(
select *,row_number() over(partition by range order by cast(userhandicap as int) rn from cte
) select * from t2 where rn<=3
您可以使用 apply
在 子查询中定义 range
值 。这是定义范围的最简单方法:
select *
from (select uu.Id, firstname, lastname, userhandicap,
row_number() over (partition by v.range order by cast(userhandicap as int)) as seqnum
from dbo.[User] uu inner join
dbo.[EventRegisteredUsers] eru
on uu.Id = eru.UserId cross apply
(values (case when userhandicap <= 5 then '0-5'
when userhandicap <= 11 then '6-11'
when UserHandicap <= 18 then '12-18'
when UserHandicap <= 26 then '19-26'
else '27 and above'
end)
) v(range)
where not exists (select 1
from dbo.[FlightPlayer] fp join
dbo.[Flight] f
on fp.FlightId = f.Id
where eru.UserId = fp.UserId and
f.Rounds = '1' and
f.Starthole = '0a9b926e-0baa-4369-8cf8-8fc84ca80d65' and
f.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
) and
eru.EventId = '7de10ad6-098d-419f-9c2d-2e62803ad1f7'
) uu
where uu.seqnum <= 3;
注意查询的其他更改:
- 不要将
not in
与子查询一起使用。如果子查询returns一个NULL
值,那么所有值都被过滤掉。这不是(通常)预期的行为。 case
表达式过于复杂。使用case
保证按顺序评估条件的事实。- 您应该在具有多个查询的查询中限定 所有 列名称。但是,不清楚这些列的来源。
- 根据您最初的逻辑(和高尔夫规则),大概
handicap
永远不会是负数,所以我很乐意删除该条件。