ROW_NUMBER() ORDER BY,不能在同一个 SELECT 语句中使用列
Posted
技术标签:
【中文标题】ROW_NUMBER() ORDER BY,不能在同一个 SELECT 语句中使用列【英文标题】:ROW_NUMBER() ORDER BY, can't use column within same SELECT statement 【发布时间】:2016-06-17 06:27:05 【问题描述】:我在下面有一个调用视图来创建排名表的过程:
CREATE PROCEDURE [dbo].[League_Table_Insert]
@LeagueName VARCHAR(30)
AS
SET NOCOUNT ON
BEGIN
DECLARE @LeagueID INT
SELECT
@LeagueID = LeagueID FROM dbo.League
WHERE LeagueName = @LeagueName
SELECT [TeamName], [Played], [Wins], [Loss], [Draws], [Points], [Goals_Scored], [Goals_Against], [Goal_Difference]
FROM League_Table
WHERE LeagueID = @LeagueID
ORDER BY Points DESC, Goal_Difference DESC;
END
查看:
CREATE VIEW League_Table
AS
SELECT f.LeagueID, t.TeamName,
SUM(
CASE WHEN f.HomeScore IS NOT NULL THEN 1 ELSE 0 END
) AS Played,
SUM(
CASE
WHEN t.TeamID = f.HomeTeamID THEN
--Home Fixture
CASE
WHEN f.HomeScore > f.AwayScore THEN 1
ELSE 0
END
WHEN t.TeamID = f.AwayTeamID THEN
CASE
WHEN f.AwayScore > f.HomeScore THEN 1
ELSE 0
END
END
) AS Wins,
SUM(
CASE
WHEN t.TeamID = f.HomeTeamID THEN
--Home Fixture
CASE
WHEN f.HomeScore < f.AwayScore THEN 1
ELSE 0
END
WHEN t.TeamID = f.AwayTeamID THEN
CASE
WHEN f.AwayScore < f.HomeScore THEN 1
ELSE 0
END
END
) AS Loss,
SUM(CASE WHEN f.HomeScore = f.AwayScore THEN 1 ELSE 0 END) as Draws,
SUM(
CASE
WHEN t.TeamID = f.AwayTeamID THEN
--Away Fixture
CASE
WHEN f.AwayScore > f.HomeScore THEN 3
WHEN f.AwayScore = f.HomeScore THEN 1
ELSE 0
END
WHEN t.TeamID = f.HomeTeamID THEN
--Home Fixture
CASE
WHEN f.HomeScore > f.AwayScore THEN 3
WHEN f.HomeScore = f.AwayScore THEN 1
ELSE 0
END
END
) AS Points,
SUM(
CASE
WHEN t.TeamID = f.HomeTeamID THEN f.HomeScore
-- Home Fixture
WHEN t.TeamID = f.AwayTeamID THEN f.AwayScore
-- Away Fixture
END
) AS Goals_Scored,
SUM(
CASE
WHEN t.TeamID = f.HomeTeamID THEN f.AwayScore
-- Home Fixture
WHEN t.TeamID = f.AwayTeamID THEN HomeScore
-- Away Fixture
END
) AS Goals_Against,
SUM(
CASE
WHEN t.TeamID = f.HomeTeamID THEN
CASE
WHEN f.HomeScore IS NOT NULL THEN f.HomeScore - f.AwayScore
-- Home Fixture
END
WHEN t.TeamID = f.AwayTeamID THEN
CASE
WHEN f.AwayScore IS NOT NULL THEN f.AwayScore - f.HomeScore
-- Away Fixture
END
END
) AS Goal_Difference
FROM dbo.Team t
--Season TBC
INNER JOIN dbo.Fixture f ON t.TeamID IN (f.HomeTeamID, f.AwayTeamID)
GROUP BY f.LeagueID, t.TeamName
下面是它的输出:
我想在视图中包含另一个字段,该字段将包含每支球队的联赛排名。我的问题是使用 ROW_NUMBER 时的 ORDER BY,因为我不确定将其设置为什么,因为我无法将其设置为“Points DESC”和“Goal_Difference DESC”,因为我在同一个 SELECT 语句中使用它创造它。我的问题是我应该在下面的代码中将 ORDER BY 设置为什么来输出正确的联赛位置?
ROW_NUMBER() OVER (PARTITION BY LeagueID ORDER BY ...) AS Position,
【问题讨论】:
个人 - 我会看看你的数据模型,因为我认为你的很多问题都可以通过在保存游戏结果时简单地包含更多信息来解决。例如记录胜利/平局/失败而不仅仅是“HomeScore”和“AwayScore”会让你的很多查询变得更加简单——对于一个相当简单的模型来说,这似乎过于复杂。在最坏的情况下,计算列可以帮助您很多。 @Allan S. Hansen:我不同意。我认为数据模型是完美的,因为它包含没有任何冗余的纯结果。并且在表上构建视图使查询数据变得简单,尽管我会让视图不聚合,以便能够查询select from view where Team_id = 5
例如。对于聚合,为方便起见,仍然可以基于非聚合视图构建视图。计算列(例如,WinningTeamID
和 LosingTeamID
是 HomeTeamID
或 AwayTeamID
或每个都为 null)当然值得在这里考虑)。
【参考方案1】:
最简单的方法可能是子查询(派生表):
CREATE VIEW League_Table AS
select
data.*,
row_number() over (partition by leagueid
order by points desc, goal_difference desc) as position,
from
(
SELECT f.LeagueID, t.TeamName,
SUM(
CASE WHEN f.HomeScore IS NOT NULL THEN 1 ELSE 0 END
) AS Played,
SUM(
...
GROUP BY f.LeagueID, t.TeamName
) data
【讨论】:
【参考方案2】:多选一个
select *, ROW_NUMBER() OVER (PARTITION BY LeagueID ORDER BY Points DESC, Goal_Difference DESC) AS Position
from <your select statement>
【讨论】:
以上是关于ROW_NUMBER() ORDER BY,不能在同一个 SELECT 语句中使用列的主要内容,如果未能解决你的问题,请参考以下文章
oracle的row_number() OVER (ORDER BY COL2 asc)和row_number() OVER (PARTITION BY COL1 ORDER BY COL2)的用法
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) 是不是保留订单?
row_number() over (partition by....order by...)用法 分组排序
ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN DESC)函数的使用