我想在两个联赛之间创建一个促销和降级,其中LeagueID 2
的前两个队员升级到LeagueID 1
,而LeagueID 1
的最后两个队伍降到{{1} }}
我的问题是如何选择那些球队,记住每个联赛的球队数量可能会在未来发生变化,所以我不能让降级球队在位置上使用where子句。我可以使用where子句来促进LeagueID 2
中的位置1和2的问题,但是如果有一种方法可以从选择和计数中进行,那么我也将使用该方法。
我知道当我们选择正确的团队时我需要做的就是更新他们的LeagueIDs。
最新消息:
LeagueID 2
'球队'表:此表是所有球队的参考,以及他们参加的联赛:
UPDATE dbo.League
SET LeagueId = 2
WHERE LeagueId = 1
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League_Table
WHERE LeagueID = 1
ORDER BY Position DESC
)
UPDATE dbo.League
SET LeagueId = 1
WHERE LeagueId = 2
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League_Table
WHERE LeagueID = 2
ORDER BY Position
)
'联赛'表:参考所有联赛:
CREATE TABLE [dbo].[Team]
(
[TeamID] TINYINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[TeamAbbreviation] CHAR(3) UNIQUE,
[TeamName] VARCHAR(50) UNIQUE,
[LeagueID] TINYINT CONSTRAINT FK_Team_League FOREIGN KEY REFERENCES League(LeagueID),
[CountryID] TINYINT CONSTRAINT FK_Team_Country FOREIGN KEY REFERENCES Country(CountryID)
)
'League_Table'表:这是从视图组成的联赛表(如上面的屏幕截图所示):
CREATE TABLE [dbo].[League]
(
[LeagueID] TINYINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[LeagueName] VARCHAR(30) UNIQUE,
[MinLeagueWeight] INT,
[MaxLeagueWeight] INT,
[CountryID] TINYINT CONSTRAINT FK_League_Country FOREIGN KEY REFERENCES Country(CountryID),
[ParentLeagueID] TINYINT CONSTRAINT FK_League_ParentLeague FOREIGN KEY REFERENCES League(LeagueID)
)
答案 0 :(得分:1)
如果你想在不同的联盟中动态使用它,你也可以使用RANK():
DECLARE @TABLE TABLE(league int, name varchar(10), position int);
INSERT INTO @TABLE
VALUES (1, 'Team A', 1),
(1, 'Team B', 2),
(1, 'Team C', 3),
(1, 'Team D', 4),
(1, 'Team E', 5),
(1, 'Team F', 6),
(1, 'Team G', 7),
(1, 'Team H', 8),
(1, 'Team I', 9),
(1, 'Team J', 10),
(1, 'Team K', 11),
(2, 'Team A', 1),
(2, 'Team B', 2),
(2, 'Team C', 3),
(2, 'Team D', 4),
(2, 'Team E', 5),
(2, 'Team F', 6),
(2, 'Team G', 7),
(2, 'Team H', 8),
(2, 'Team I', 9),
(2, 'Team J', 10),
(2, 'Team K', 11);
SELECT league, name, position
FROM (SELECT *
, RANK() OVER (PARTITION BY league ORDER BY position ASC) AS TopRank
, RANK() OVER (PARTITION BY league ORDER BY position DESC) AS BottomRank
FROM @TABLE) RankedResults
WHERE TopRank <= 2
OR BottomRank <= 2;
结果:
league name position
----------- ---------- -----------
1 Team K 11
1 Team J 10
1 Team B 2
1 Team A 1
2 Team K 11
2 Team J 10
2 Team B 2
2 Team A 1
编辑:TopRanked字段显然不是真正需要的,因为你可以只过滤位置,但作为一种解释我的方法的目的。
答案 1 :(得分:0)
无论有多少
,您都可以为底部两个下降SELECT TOP 2 *
FROM Teams
WHERE LeagueID = 1
ORDER BY Position DESC
(旁注:我希望您的Position
字段是计算出来的,因为如果您保留它可能会影响数据的完整性,那么
你的2个问题很好,尽管可能,但将它们组合成一个查询将不太清楚。您只是在子查询
中缺少WHERE
子句
UPDATE dbo.League
SET LeagueId = 2
WHERE LeagueId = 1
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League
WHERE LeagueID = 1
ORDER BY Position DESC
)
UPDATE dbo.League
SET LeagueId = 1
WHERE LeagueId = 2
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League
WHERE LeagueID = 2
ORDER BY Position
)
另一个尝试 - 这次只有一个查询。 H / T给@Jens提供测试用例。
如果你首先弄清楚每个球队的联赛位置如何变化:
SELECT LeagueID, TeamName, case
when league>1 AND RANK() OVER (PARTITION BY league ORDER BY position ASC) <= 2 THEN -1
when league<2 AND RANK() OVER (PARTITION BY league ORDER BY position DESC) <= 2 THEN 1
else 0
end as leaguechange
FROM dbo.League_Table
(注意我在那里增加了2个条款 - league>1
以阻止球队晋级联赛0和league<2
以阻止球队降级到联赛3 - 这两个都可以调整相应地)
完成后,它可以在单个UPDATE
中用作子查询:
UPDATE dbo.Team
SET LeagueID = LeagueID + leaguechange
FROM (
SELECT LeagueID, TeamName, case
when league>1 AND RANK() OVER (PARTITION BY leagueID ORDER BY position ASC) <= 2 THEN -1
when league<2 AND RANK() OVER (PARTITION BY leagueID ORDER BY position DESC) <= 2 THEN 1
else 0
end as leaguechange
FROM dbo.League_Table
) c
INNER JOIN dbo.Team t
ON c.LeagueId = t.LeagueID
AND c.TeamName = t.TeamName
答案 2 :(得分:0)
WITH NewLeague AS
(
SELECT NewLeagueId = CASE WHEN LeagueId = 1 THEN 2 ELSE 1 END, *
FROM dbo.League
WHERE
(
LeagueId = 1
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League
ORDER BY Position DESC
)
)
OR
(
LeagueId = 2
AND Position IN
(
SELECT TOP 2 Position
FROM dbo.League
ORDER BY Position ASC
)
)
)
UPDATE NewLeague
SET LeagueId = NewLeagueId
如果你想结合降级和升级的更新声明,可以使用:
{{1}}