【问题标题】:nesting sql select in another sql select?将sql select嵌套在另一个sql select中?
【发布时间】:2011-11-09 09:26:25
【问题描述】:

这是一个非常常见的用例,但我从来不知道最好的方法。假设我有两张桌子

团队表
- 身份证
- 团队名称

球员表
- 身份证
- team_id
- 玩家名称

在输出 html 中说我想显示球队的标题,并在每个球队的下方显示各自的球员:

第 1 队
- 鲍勃
- 乔恩

第 2 队
- 肯
- 杰森

以前我一直对团队使用 select 语句,在循环遍历结果时,执行另一个 select 语句,其中外键将等于外部查询的当前行的 ID。这是一种愚蠢、低效的做法吗?做这样的事情的标准方法是什么?我可以使用 join 但我想我需要添加一些逻辑来只显示一次团队标题。我用的是php+mysql。

【问题讨论】:

    标签: sql select nested


    【解决方案1】:

    通常循环遍历一个结果集并在循环内查询更多信息并不是一个好主意。如果可能,最好避免循环中的数据库查询。正如您所建议的那样, 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
    

    然后您可以循环遍历数组并输出您想要的结果。 或者您可以直接循环遍历数据库结果并在存储团队名称时输出它们,并且仅在它更改时输出。我会推荐前一种解决方案。它更干净,更抽象。

    【讨论】:

      【解决方案2】:

      您有两个选择,连接或子查询。每个连接都可以转换为另一个连接中的子查询。

      减少查询的标准方法:

      整个团队表中的第一个选择。

      然后遍历你的结果,for x in team names : 以及每个团队的简单选择 where team_id = x。

      您会注意到不需要子查询,只需编码逻辑即可。

      【讨论】:

      • 这不是和我的例子一样的解决方案吗?
      • 它可能是,但我相信它是最好的。最好的解决方案并不意味着只用一个查询就可以得到你想要的一切;)这里没有连接,没有子查询,因为你不需要一个。如果您的问题是没有 n^2 的复杂性,这是无法完成的,您需要遍历第一组,或者您的数据库将在连接或子查询的情况下进行。相同 = 相同
      【解决方案3】:

      您正在做的是合并 player_name 列。从 SQL 2008R2 开始,没有聚合连接字符串函数 - 除非您使用 dot net 框架编写并在使用此技术的所有数据库中启用它。

      一种适用于所有当前支持的版本的方式 - 2005 +

      创建一个用户定义的函数,它接受团队的 id 并返回一个名称字符串(按您想要的任何顺序)

      你查询然后变成

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

      在函数内部连接字符串

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

      您可以使用一些奇特的大小写逻辑来确保仅在 @Output ''

      时添加分隔符' - '

      您可以通过传递参数来扩展您的函数以按不同的顺序排序。该解决方案非常易读-可能有一种子查询方式来执行此操作-但是子查询总是让我头疼!函数方法不适用于非常大的表 - 你的大脑可能会受到伤害。

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2021-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-31
        • 1970-01-01
        相关资源
        最近更新 更多