2011-11-09 156 views
1

這是一個非常常見的用例,但我從來不知道這樣做的最佳方式。說我有兩個表嵌套sql select在另一個sql select?

隊表
- ID
- 球隊名稱

球員表
- ID
- TEAM_ID
- PLAYER_NAME

說,在輸出HTML我想顯示隊伍的標題,並且在每個隊伍下面各自的隊員:

團隊1
鮑勃 -
- 喬恩

隊2
- 肯
賈森 -

此前我一直使用select語句的隊伍,而通循環的結果,執行另一個選擇語句,其中外鍵將等於外部查詢的當前行的ID。這是否是一種愚蠢,無效的方式呢?做這種事的標準方式是什麼?我可以使用加入,但我想我需要添加一些邏輯來僅顯示一次球隊標題。我正在使用php + mysql。

回答

2

通常循環一個結果集並查詢循環內的更多信息不是一個好主意。如果可能,最好避免循環中的數據庫查詢。正如你所建議的JOIN會在這裏工作:

SELECT team_name,player_name FROM team INNER JOIN players on team.id=players.team_id 

有很多方法可以在PHP中處理結果。您可以遍歷結果並將其添加到數組中

array(
    team1 => array(
     bob, 
     jon 
    ), 
    team2 => array(etc 

然後,您可以遍歷數組並輸出結果。 或者您可以直接循環訪問數據庫結果,並在您存儲團隊名稱時輸出它們,並在更改時僅輸出它們。我會推薦以前的解決方案。它更乾淨,抽象更好。

0

你有兩個選擇,一個連接或一個子查詢。每個連接總是可以被翻譯成另一個子查詢。

的標準方法少做查詢:

對整個團隊表中的第一選擇。

然後遍歷您的結果,對於團隊名稱中的x: 以及每個團隊的簡單選擇,其中team_id = x。

你會注意到不需要子查詢,只需要編碼邏輯。

+0

是不是像我的例子那樣的解決方案? – eirikrl

+0

好吧,但我相信它是最好的。最好的解決方案並不意味着只需要一個查詢即可獲得所有你想要的;)這裏沒有連接,也沒有子查詢,因爲你不需要連接。如果你的麻煩是沒有n^2的複雜性,那不可能完成,你需要循環第一個集合,否則你的數據庫將在連接或子查詢的情況下進行。相同=相同 – Jerome

0

你在做什麼是conconating player_name列。從SQL 2008R2開始,不存在聚合conconcate字符串函數 - 除非您使用dot net框架編寫並在所有使用此技術的數據庫中啓用它。

的方式,將與目前所有支持版本的工作 - 2005 +

創建用戶定義的函數,它接受了球隊的ID,並返回名稱的字符串(在任何你想要的順序)

您查詢就變成

SELECT team_name, dbo.af_PayerNames(team_ID) Players FROM [Team tabel] 

要conconate函數內部的串

DECLARE @Output VARCHAR(4000) 
SET @Output = '' 
SELECT @Output = @output + ' - ' + COALESCE(Player_Name, '') FROM Players where TeamId = @ param 

你可以使用一些花哨的情況下的邏輯,以確保分隔符「 - 」只加在@Output <>'

您可以擴展功能,通過不同的順序傳遞一個參數去排序。該解決方案非常可讀 - 可能有一個子查詢的方式 - 但子查詢alwways讓我頭痛!功能方法不適合用於非常大的桌子 - 你的大腦可能會受傷。

希望這有助於