2011-11-09 155 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让我头痛!功能方法不适合用于非常大的桌子 - 你的大脑可能会受伤。

希望这有助于