需要一些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;
希望有人可以提供我需要如何更改查询的见解。
答案 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.