【问题标题】:Fetch all rows for a foreign key if even one row matches condition如果甚至一行匹配条件,则获取外键的所有行
【发布时间】:2014-02-28 08:55:30
【问题描述】:

我有两张桌子profileprops

profile.IDprops 与其他列的外键。

我需要用条件查询表props,但返回所有与满足条件的行具有相同外键的行。

例子:

+---------------------+
|ID  |  name  | value |
+---------------------+
|1   |  eng   | 60    |
|1   |  mat   | 70    |
|1   |  sci   | 80    |
|2   |  eng   | 90    |
|2   |  mat   | 40    |
|2   |  sci   | 50    |
|3   |  eng   | 70    |
|3   |  mat   | 40    |
|3   |  sci   | 50    |
+---------------------+

对于上表,如果我查询name = 'mat' AND value < 50,我得到

+---------------------+
|ID  |  name  | value |
+---------------------+
|2   |  mat   | 40    |
|3   |  mat   | 40    |
+---------------------+

我需要

+---------------------+
|ID  |  name  | value |
+---------------------+
|2   |  eng   | 90    |
|2   |  mat   | 40    |
|2   |  sci   | 50    |
|3   |  eng   | 70    |
|3   |  mat   | 40    |
|3   |  sci   | 50    |
+---------------------+

对于那些质疑目的的人,我正在尝试为配置文件实现动态属性;并且需要完整的属性列表以进一步过滤具有任何其他条件的属性。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您也可以使用INNER JOIN 代替WHERE id IN... 语句来完成此操作:

    SELECT  A.ID,
            A.Name,
            A.Value
      FROM  props A
        INNER JOIN (SELECT  ID
                      FROM  props
                      WHERE (Name = 'mat' AND value < 50)) B ON B.ID = A.ID 
    

    所以在B 中获取所有符合条件的IDs,然后简单地将它们加入props 表(别名A)。

    【讨论】:

    • 我也考虑过这个解决方案,但它也需要子查询,一个简单的子查询可能更容易理解。
    • 这比 in 快
    • 这取决于数据库引擎。 Oracle 11 查询优化器(也许还有 10 个,我不知道)将这些情况转换为 JOIN AFAIK。我听说现在大多数查询优化器都是这样做的。
    • 而且它仍然是引用同一张表的子查询。如果实现联接而不是子查询,则联接会更快。在这两种情况下,子查询的成本都是数据库引擎的主要成本。
    • 内连接有显着的性能提升。虽然我使用的是 mysql,但似乎 InnoDB 引擎不会将 IN 转换为 JOIN。
    【解决方案2】:
    SELECT *
      FROM props
      WHERE id IN
      (
         SELECT id
           FROM props
           WHERE name = 'mat' AND value < 50
      )
    

    【讨论】:

    • 刚试了一下,回来看看这个答案。奇迹般有效。可以在 8 分钟内添加为答案
    • 在 MySQL 中引用同一张表的子查询确实不是一个好习惯
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 2012-08-21
    • 2011-04-20
    • 2021-03-03
    • 2021-03-15
    • 1970-01-01
    • 2016-03-21
    • 2022-06-28
    相关资源
    最近更新 更多