2017-07-17 45 views
3

我想要做一個嵌套查詢,並且遇到了一些麻煩。我有兩個表(針對這個問題簡化)與玩家信息,另一個表與團隊信息。我的最終目標是找到不止一個球隊的球員,然後打印出他們所在的球隊。將sql查詢輸出提供給一個「for-each」風格的新sql

我的MS SQL Server 2014這是我的問題的一小圖示(注意,我從這個測試我的數據庫的初始化代碼設置省略了最後的小組)創建了一個sqlfiddle for testing [編輯:] sqlfiddle網站是有一些問題,所以我已經把它貼我的數據庫的初始化代碼 [EDIT2:] sqlfiddle再次高達

CREATE TABLE Players (
    userid int NOT NULL, 
    name char(10) NOT NULL, 
    CONSTRAINT [PK_Players] PRIMARY KEY CLUSTERED ([userid]), 
); 

INSERT INTO Players (userid,name) VALUES 
(0,'Tim'), 
(1,'John'), 
(2,'Amy'), 
(3,'Stacy'), 
(4,'Craig'), 
(5,'Adam'), 
(6,'Rachael'), 
(7,'Steve'), 
(8,'Mitch'); 

CREATE TABLE Teams (
    teamid int, 
    team_name char(10), 
    player0 int, 
    player1 int, 
    player2 int, 
    player3 int 
    CONSTRAINT [PK_Teams] PRIMARY KEY CLUSTERED ([teamid]), 
    -- Says that each of the Player# must correspond to a userid in the Players Table 
    CONSTRAINT [p0_2_player_tbl] FOREIGN KEY ([player0]) REFERENCES [dbo].[Players] ([userid]), 
    CONSTRAINT [p1_2_player_tbl] FOREIGN KEY ([player1]) REFERENCES [dbo].[Players] ([userid]), 
    CONSTRAINT [p2_2_player_tbl] FOREIGN KEY ([player2]) REFERENCES [dbo].[Players] ([userid]), 
    CONSTRAINT [p3_2_player_tbl] FOREIGN KEY ([player3]) REFERENCES [dbo].[Players] ([userid]), 
    ); 

INSERT INTO Teams(teamid, team_name, player0,player1,player2,player3) VALUES 
(0,'green',0,1,2,3), 
(1,'red' ,4,2,5,0), 
(2,'blue' ,6,7,8,2), 
-- (3,'black',2,2,2,NULL); 

enter image description here

到目前爲止,我已經成功地找到多個團隊

-- this portion in parenthesis Finds all the players on multiple teams 
SELECT userid,name,count(*) as 'Num Occurances' 
FROM Players 
INNER JOIN Teams 
    ON player0=Players.Userid 
    OR player1=Players.Userid 
    OR player2=Players.Userid 
    OR player3=Players.Userid 
GROUP BY userid,name 
HAVING COUNT(*) > 1; 

find duplicates result

我也寫了代碼示例fidn了球員所屬球隊所有的球員。正如你可以看到我已經明確地搜索userid = 0

/*I think I want to take the userids returned, and fnd what team 
they are on*/ 
SELECT teamid,team_name 
FROM Teams 
WHERE 
    Player0=0 -- Instead of typing the ID directly 
    OR Player1=0 -- I'd like to get it from the 
    OR Player2=0 -- previous query 
    OR Player3=0 
; 

resolve names to teams

最終我的目標是做一個嵌套查詢,其中來自我的球員多支球隊的第一個查詢輸出將輸入到我的teamid查詢查詢。我到目前爲止開發了這個,但它不工作究竟我如何喜歡

/*Issues combining the two statements, I'm not sure how to do this 
I made this attempt, but It's not quite right, it list every team 
and the two players, (thing of oring Player0=0 OR Player0=2 
I want a list of each player and the teams they belong to*/ 
SELECT name,team_name 
FROM Players,Teams 
WHERE userid IN (
-- this portion in parenthesis Finds all the players on multiple teams 
SELECT userid -- ,name,count(*) as 'Num Occurances' 
FROM Players 
INNER JOIN Teams 
    ON player0=Players.Userid 
    OR player1=Players.Userid 
    OR player2=Players.Userid 
    OR player3=Players.Userid 
GROUP BY userid,name 
HAVING COUNT(*) > 1 
) GROUP BY name,team_name 
ORDER BY name ASC; 

然而,這是給我團隊任何副本(覺得做Player0 = 0 OR player0 = 2),如紅色

current incorrect sql output

我想什麼下面看到類似的東西「爲每個」式循環。我們在哪裏搜索的球隊EACH從前一個查詢返回的球員而不是搜索球隊ANY球員從前一個查詢返回。你可以看到下面我的目標輸出(綠色)

desired SQL ouput

+0

查看「Common Table Expressions」或CTE。 – pmbAustin

+0

有效使用SQL最大的關鍵是從程序思維轉換爲基於集合的思維模式。不要想着如何通過數據來獲得結果。想想你如何結合你的數據集(表),以儘可能少的次數獲得你想要的結果。大多數SQL的風格可以用數據做一些非常漂亮的事情。 – Shawn

回答

2

COUNT OVER來計算每個用戶的團隊數。然後保留那些數量大於1的記錄。

SELECT userid, user_name, teamid, team_name 
FROM 
(
    SELECT 
    p.userid, 
    p.name AS user_name, 
    t.teamid, 
    t.team_name, 
    COUNT(*) OVER (PARTITION BY p.userid) AS num_teams 
    FROM Players p 
    JOIN Teams t ON p.Userid IN (t.player0, t.player1, t.player2, t.player3) 
) counted 
WHERE num_teams > 1; 
+0

@Santi:感謝編輯。 –

+0

不是問題,很好的答案! +1 – Santi

2

SQL總是提供了多種可能的解決方案,但我會盡我的手在這裏提供一個。

您的內部查詢應該簡單地獲取多個團隊(您已經完成)的玩家,外部查詢可以將這些結果加入「團隊」表。

SELECT name, team_name FROM (
    SELECT userid, name 
    FROM Players 
    INNER JOIN Teams ON 
     Players.userid IN (player0, player1, player2, player3) 
    GROUP BY userid, name 
    HAVING COUNT(*) > 1 
) a 
INNER JOIN Teams ON userid IN (player0, player1, player2, player3) 
ORDER BY Name ASC 

注:我已經修改了此...

player0=Players.Userid 
OR player1=Players.Userid 
OR player2=Players.Userid 
OR player3=Players.Userid 

...這個...

Players.Userid IN (player0, player1, player2, player3) 

...只是查詢了一下清潔。

+0

感謝您的快速幫助,這是一個很好的解決方案。正如你所說的其中之一,我非常感謝,+1 – andrew