【问题标题】:Selecting records where all joined rows match选择所有连接行匹配的记录
【发布时间】:2017-01-09 23:56:40
【问题描述】:

给定以下架构:

employees
id | name

employee_attributes
id | employee_id | key | value

我想选择所有具有所提供属性的员工。

以下语句有效:

SELECT employees.* FROM employees
INNER JOIN employee_attributes ON employee_attributes.employee_id = employees.id
WHERE employee_attributes.key = 'foo' AND employee_attributes.value = 'bar'

但只允许我通过一个属性找到员工。如何调整它以通过多个属性检索员工?

需要明确的是,如果我提供 两组 属性来匹配,则查询应该只返回具有至少这两个属性的员工。

例如,如果 Bob 只有一个属性:

key | value
===========
foo | bar

但我为查询提供了两个属性(foobarbinbaz),不应返回 Bob。

【问题讨论】:

    标签: mysql sql join


    【解决方案1】:

    以下应该可以工作:

    SELECT employees.id, employees.name, count(employee_attributes.id) as attribute_count FROM employees
    INNER JOIN employee_attributes ON employee_attributes.employee_id = employees.id
    WHERE (employee_attributes.key = 'foo' AND employee_attributes.value = 'bar') OR (employee_attributes.key = 'bin' AND employee_attributes.value = 'baz')
    group by employees.id, employees.name
    having attribute_count >= 2;
    

    【讨论】:

      【解决方案2】:

      您可以使用聚合获取员工 ID:

      SELECT ea.employee_id
      FROM employee_attributes.employee_id 
      WHERE (ea.key = 'foo' AND ea.value = 'bar') OR
            (ea.key = 'bin' AND ea.value = 'baz')
      GROUP BY ea.employee_id
      HAVING COUNT(DISTINCT ea.key) = 2;
      

      有关完整信息,您可以使用JOIN

      SELECT e.*
      FROM employee e JOIN
           (SELECT ea.employee_id
            FROM employee_attributes.employee_id 
            WHERE (ea.key = 'foo' AND ea.value = 'bar') OR
                  (ea.key = 'bin' AND ea.value = 'baz')
            GROUP BY ea.employee_id
            HAVING COUNT(DISTINCT ea.key) = 2
           ) ea
           ON ea.employee_id = e.id;
      

      【讨论】:

        【解决方案3】:

        使用条件聚合:

        SELECT employees.*
        FROM employees
        INNER JOIN employee_attributes
            ON employee_attributes.employee_id = employees.id
        GROUP BY employee_attributes.employee_id
        HAVING SUM(CASE WHEN employee_attributes.key = 'foo' AND
                             employee_attributes.value = 'bar' THEN 1 ELSE 0 END) > 0 AND
               SUM(CASE WHEN employee_attributes.key = 'bin' AND
                             employee_attributes.value = 'baz' THEN 1 ELSE 0 END) > 0
        

        【讨论】:

        • 这也将返回只有一个键值对的员工。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        • 2015-09-09
        • 2019-05-26
        • 1970-01-01
        • 2016-06-01
        • 1970-01-01
        相关资源
        最近更新 更多