【问题标题】:Postgresql-Select one row from table where value in many table matches?Postgresql-从许多表中的值匹配的表中选择一行?
【发布时间】:2013-07-12 16:24:03
【问题描述】:

我有两个表,分别称为 a 和 b,其中 a 与 b 以一对多的关系相关。我想从表 a 中选择任何行,其中表 b 中的许多相关记录中的任何一个都与条件匹配。基本连接不起作用,因为这将为表 b 中匹配的每一行返回一个结果 - 我只希望表 a 中的每一行都有一个结果,并且有一个或多个相关记录匹配。

举个简单的例子,假设我有一个表 Departments 和相关表Employees,其中每个员工都有一个部门,但每个部门显然可以有多个员工。我想要一个查询,每个部门有一个或多个员工符合给定标准的一行 - 比如说有一个或多个员工获得“本月最佳员工”的部门。我该怎么做?谢谢。

【问题讨论】:

    标签: postgresql


    【解决方案1】:
    SELECT * FROM department d
    WHERE EXISTS (
       SELECT * FROM employee e
       JOIN badges b ON b.person_id = e.person_id AND b.badge = 'EotM'
       WHERE e.dep_id = d.dep_id
       AND e.gender = 'F'
       );
    

    【讨论】:

      【解决方案2】:

      听起来像是子查询的工作。类似于: Select * from dept where id in (select deptID from Emp where wasEOTM = true);应该做的工作。

      【讨论】:

      • 是的,这行得通。现在我因为没有想到它而感到愚蠢。我想我只是专注于连接:P
      • @Clodoaldo Neto 感谢您的提醒,但是在我的数据库上使用解释分析进行的一些快速测试表明,这种方法的速度大约是您建议的方法的两倍(SELECT DISTINCT ON)。当然,我喜欢你的提议,因为它只保留 WHERE 子句作为标准,这使它更容易适应我现有的工作流程。
      【解决方案3】:
      select distinct on (d.id)
          d.name
      from
          department d
          inner join
          employee e on d.id = e.department_id
      where e.age between 60 and 65
      

      如何按任意列排序:

      select *
      from (
          select distinct on (d.id)
              d.*
          from
              department d
              inner join
              employee e on d.id = e.department_id
          where e.age between 60 and 65
      ) s
      order by name
      

      【讨论】:

      • 我喜欢这种方法,因为它非常适合我的工作流程,并且不使用任何子查询。但是,似乎必须使用 distinct 子句中的表达式作为初始 order by,这有点臭。
      • @ibrewster 我更新了一个可以按任何列订购的版本。话虽如此,使用exists 接受的答案会更快。
      • 是的,这行得通。但是,正如您所说,exists 更快,对于我正在处理的特定应用程序,这是必不可少的。不过很遗憾,因为我实际上更喜欢你的回答:-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2014-10-25
      • 2017-01-08
      • 2017-02-23
      • 2021-03-11
      相关资源
      最近更新 更多