选择所有连接行匹配的记录

时间:2017-01-09 23:56:41

标签: mysql sql join

给出以下架构:

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。

3 个答案:

答案 0 :(得分:0)

使用条件聚合:

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

答案 1 :(得分:0)

以下应该工作:

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 :(得分:0)

您可以使用聚合获取员工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;