2014-01-22 3 views
0

В MySQL имеет м-н отношение между сотрудниками и позицией таблиц с использованием таблицы соединений employees_positions. Я нашел способ передать position_id и получить сотрудников, у которых есть эта позиция.MySQL использования и для подзапроса - фильтр ResultSet

Однако я бы также передал два [или более] position_id и извлек сотрудников, у которых есть ОБА [или ВСЕ] position_id прошло.

Например ищет разработчиков и менеджеров вернутся как ЛПП и FRANK

DB Код создания:

CREATE TABLE `employees` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    PRIMARY KEY (`id`) 
) ; 

INSERT INTO `employees` (`id`, `name`) VALUES 
    (1, 'bob'), 
    (2, 'frank'), 
    (3, 'jim'), 
    (4, 'paul'), 
    (5, 'mick'); 

CREATE TABLE `employees_positions` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `employe_id` int(11) NOT NULL, 
    `position_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `Index 2` (`position_id`,`employe_id`) 
); 

INSERT INTO `employees_positions` (`id`, `employe_id`, `position_id`) VALUES 
    (1, 1, 1), 
    (2, 2, 1), 
    (3, 3, 3), 
    (4, 4, 3), 
    (5, 5, 3), 
    (6, 1, 2), 
    (7, 1, 3), 
    (8, 2, 2); 

CREATE TABLE `positions` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    PRIMARY KEY (`id`) 
) ; 

INSERT INTO `positions` (`id`, `name`) VALUES 
    (1, 'manager'), 
    (2, 'developer'), 
    (3, 'executive'); 

На данный момент я использую этот запрос для получения также позиции возвращенных сотрудников:

SELECT 
    name, 
    (SELECT 
     GROUP_CONCAT(p.name) 
    FROM positions AS p 
     LEFT JOIN employees_positions AS e_p 
     ON p.id = e_p.position_id 
    WHERE e_p.employe_id = e.id) AS positionsHeld, 
    (SELECT 
     GROUP_CONCAT(p.id) 
    FROM positions AS p 
     LEFT JOIN employees_positions AS e_p 
     ON p.id = e_p.position_id 
    WHERE e_p.employe_id = e.id) AS positionIDs 

FROM employees AS e; 

Но я хотел бы вернуться только те элементы, которые имеют все требуемые positions_id

ответ

1

Богемиан дал хороший ответ, если только сотрудник был назначен только на должность.
Другой способ, что вы могли бы сделать это было бы:

select emp.id, emp.name, 
     group_concat(p.name) as positions_held, 
     group_concat(p.id) as position_ids 
    from employees emp 
    join employees_positions epos on epos.employe_id = emp.id 
    join positions p on p.id = epos.position_id 
    join employees_positions epos1 on epos1.employe_id = emp.id and epos1.position_id = 1 
    join employees_positions epos2 on epos2.employe_id = emp.id and epos2.position_id = 2 
group by emp.id, emp.name; 

Как вы добавили больше позиций, вы бы просто добавить несколько строк, как:

join employees_positions epos1 on epos1.employe_id = emp.id and epos1.position_id = 1 

GROUP_CONCAT даст вам список всех позиции, которые был у сотрудника, а не только те, которые соответствуют предоставленным позициям. Но данные предоставленных позиций являются статическими и не будут меняться в строке за строкой, поэтому вы можете просто использовать свое приложение для вставки этих данных.

Link to SQL Fiddle

1

Используйте пункт HAVING, чтобы гарантировать, что они имеют обе позиции:

SELECT e.name 
FROM employees e 
JOIN employees_positions e_p ON e_p.employe_id = e.id 
WHERE e_p.position_id in (1,2) 
GROUP BY 1 
HAVING count(*) = 2 

См SQLFiddle

Обратите внимание, что вам не нужно group_concat() или присоединиться к position столу, но если вы действительно необходимо, чтобы:

SELECT e.name, group_concat(p.name order by 1) postitions 
FROM employees e 
JOIN employees_positions e_p ON e_p.employe_id = e.id 
JOIN positions p ON p.id = e_p.position_id 
WHERE p.id in (1,2) 
GROUP BY 1 
HAVING count(*) = 2 

См. Тот же SQLFiddle выше (у него есть оба запроса).

Смежные вопросы