SQL Server从表中获取最新行加入另一个表

时间:2014-08-13 14:40:58

标签: sql sql-server

需要一些SQL Server查询帮助。

差不多,我需要显示所有具有相应最新状态的玩家。我已按照以下方式设计了我的查询,但没有任何状态的玩家没有出现。我需要将该播放器显示在列表中,并且他的StatusDesc将只是NULL。

从我的最终选择查询中可以看出,我错过了一个在PlayerStatus表中没有记录的玩家(Ray Allen)。

设置如下:

/*Create the Temp Tables*/

CREATE TABLE #Player(
PlayerID int,
PlayerName varchar(50), 
PlayerTeam varchar(150));

CREATE TABLE #PlayerStatus(
PlayerStatusID int IDENTITY(1, 1),
PlayerID int,
StatusID int,
CreatedDate date);

CREATE TABLE #Status(
StatusID int,
StatusDesc varchar(20));

/* Populate Tables */
INSERT INTO #Player VALUES(1, 'Tim Duncan', 'Spurs');
INSERT INTO #Player VALUES(2, 'Tony Parker', 'Spurs');
INSERT INTO #Player VALUES(3, 'Manu Ginobili', 'Spurs');
INSERT INTO #Player VALUES(4, 'Boris Diaw', 'Spurs');
INSERT INTO #Player VALUES(5, 'Kawhi Leonard', 'Spurs');

INSERT INTO #Player VALUES(6, 'Lebron James', 'Heat');
INSERT INTO #Player VALUES(7, 'Dwayne Wade', 'Heat');
INSERT INTO #Player VALUES(8, 'Chris Bosh', 'Heat');
INSERT INTO #Player VALUES(9, 'Mario Chalmers', 'Heat');
INSERT INTO #Player VALUES(10, 'Udonis Haslem', 'Heat');
INSERT INTO #Player VALUES(11, 'Ray Allen', 'Heat');


INSERT INTO #PlayerStatus(PlayerID, StatusID, CreatedDate)
SELECT PlayerID, 1, GETDATE()
FROM #Player;

INSERT INTO #PlayerStatus(PlayerID, StatusID, CreatedDate)
VALUES(8, 4, GETDATE());

DELETE FROM #PlayerStatus WHERE PlayerID = 11;

INSERT INTO #Status(StatusID, StatusDesc)
VALUES(1, 'Healthy');

INSERT INTO #Status(StatusID, StatusDesc)
VALUES(2, 'Injured');

INSERT INTO #Status(StatusID, StatusDesc)
VALUES(3, 'Retired');

INSERT INTO #Status(StatusID, StatusDesc)
VALUES(4, 'Reserved');

--SELECT * FROM #Player;
--SELECT * FROM #PlayerStatus;
--SELECT * FROM #Status;

/* Select all Players and their Status */
SELECT ply.PlayerName, ply.PlayerTeam, sta.StatusDesc, pls.CreatedDate
FROM #PlayerStatus pls
INNER JOIN #Player ply ON ply.PlayerID = pls.PlayerID
INNER JOIN #Status sta ON pls.StatusID = sta.StatusID
LEFT JOIN #PlayerStatus pls2 ON pls2.PlayerID = pls.PlayerID AND pls2.PlayerStatusID > pls.PlayerStatusID
WHERE pls2.PlayerStatusID IS NULL
ORDER BY ply.PlayerID ASC;

DROP Table #Player;
DROP Table #PlayerStatus;
DROP Table #Status;

希望有人可以提供我需要如何更改查询的见解。

1 个答案:

答案 0 :(得分:1)

你关闭 - 你只需要从Player表开始,而不是使用PlayerStatus,并使用LEFT JOIN。

/* Select all Players and their Status */
SELECT ply.PlayerName, ply.PlayerTeam, sta.StatusDesc, pls.CreatedDate
FROM #Player ply
LEFT JOIN #PlayerStatus pls ON ply.PlayerID = pls.PlayerID
LEFT JOIN #Status sta ON pls.StatusID = sta.StatusID
LEFT JOIN #PlayerStatus pls2 ON pls2.PlayerID = pls.PlayerID AND pls2.PlayerStatusID > pls.PlayerStatusID
WHERE pls2.PlayerStatusID IS NULL
ORDER BY ply.PlayerID ASC;

您的原始查询以PlayerStatus开头,并从那里链接出来,所以它只是从PlayerStatus表中存在的那些值开始。

您还使用了INNER JOIN,这会将结果限制为仅匹配的记录。我认为使用LEFT JOIN代替(或RIGHT JOIN,但我发现使用LEFT JOIN更容易阅读)将允许您从第一个表中检索所有记录,无论是否他们在第二张表中有一个匹配。 See here.