Оператор SQL выбирает столбцы с определенным значением - PullRequest
0 голосов
/ 29 сентября 2018

Мне нужна помощь, чтобы сделать заявление SQL;Я действительно не знаю, как выйти из ситуации.У меня есть две таблицы: «Отделы» и «Сотрудники», из которых я хочу выбрать Dpt_num и Dpt_name отделов, в которых есть хотя бы один сотрудник и все их сотрудники из Барселоны

Дело 1

== Departments =======
| Dpt_num | Dpt_name |
|    1    |    A     |
|    2    |    B     |

== Employees ===================
| E_num | Dpt_num |  City      |
|  1    |   1     | Barcelona  |
|  2    |   1     | Barcelona  |

Результат в этом случае должен быть

 Dpt_num Dpt_name
 ------------------
    1       A

Дело 2

== Departments =======
| Dpt_num | Dpt_name |
|    1    |    A     |
|    2    |    B     |

== Employees ==================
| E_num | Dpt_num | City      |
|   1   |    1    | Barcelona |
|   2   |    1    | Madrid    |

Результат в этом случае должен быть пустым.

Я пробовал это на примере, но он кажется очень неэффективным и не работает во всех случаях

select
    num_dpt, nom_dpt
from
    departements
where
    1 = (select count(distinct e.ciutat_empl)
         from empleats e
         where e.num_dpt = num_dpt)
    and not exists (select * from empleats e
                    where e.ciutat_empl != 'BARCELONA' and e.num_dpt = num_dpt);

Я действительно ценюлюбая помощь.Спасибо!

Ответы [ 6 ]

0 голосов
/ 29 сентября 2018

demo: db <> fiddle

SELECT dpt_num, dpt_name
FROM (
    SELECT d.dpt_num, d.dpt_name, array_agg(city) as cities
    FROM dept d
    JOIN empl e
    ON d.dpt_num = e.dpt_num
    GROUP BY d.dpt_num, d.dpt_name
) s
WHERE 'Barcelona' = ALL(cities)

Объедините города, а затем вы можете выполнить фильтрацию с помощью оператора ALL, который проверяет, все ли элементы массива соответствуют условию.

0 голосов
/ 29 сентября 2018

Пожалуйста, попробуйте запрос ниже

select a.dpt_number,a.dpt_name from yy_department a 
where exists (select 'x' from yy_employees y where y.dpt_number = a.dpt_number and y.city = 'Barcelona') 
and not exists (select 'x' from yy_employees y where y.dpt_number = a.dpt_number and nvl(y.city,'x') <> nvl('Barcelona','y'))
0 голосов
/ 29 сентября 2018

Вообще говоря, вы сравниваете COUNT(*) с COUNT(some condition) для таких задач:

SELECT *
FROM Departments
WHERE EXISTS (
    SELECT 1
    FROM   Employees
    WHERE  Employees.Dpt_num = Departments.Dpt_num
    HAVING COUNT(*) > 0 -- it is possible to get a 0 if where did not match
    AND    COUNT(*) = COUNT(CASE WHEN Employees.City = 'Barcelona' THEN 1 END)
)

DB Fiddle

0 голосов
/ 29 сентября 2018

Вы хотите пойти по пути выполнения фильтрации в предложении where.Затем используйте exists и not exists:

select d.num_dpt, d.nom_dpt 
from departaments d
where exists (select 1
              from empleats e
              where e.num_dpt = d.num_dpt and e.ciutat_empl = 'BARCELONA' 
             ) and
      not exists (select 1
                  from empleats e
                  where e.num_dpt = d.num_dpt and e.ciutat_empl <> 'BARCELONA' 
             );

Первое условие проверяет, что хотя бы один сотрудник из Барселоны.Второй проверяет, что ни один сотрудник не является сотрудником какого-либо другого города.

Одной из основных проблем в вашей версии является предложение о корреляции:

e.num_dpt = num_dpt

Вы думаете, что это происходит:

e.num_dpt = departaments.num_dpt

Но это действительно так:

e.num_dpt = e.num_dpt

Всегда уточняйте имена столбцов.Это особенно важно, когда в запросе имеется более одной ссылки на таблицу.

0 голосов
/ 29 сентября 2018

Я считаю, что это должно сработать:

select d.dpt_num, d.dpt_name
from departments d
inner join employees e on
  d.dpt_num = e.dpt_num
group by d.dpt_num, d.dpt_name
having count(*) = sum(case when e.city = 'Barcelona' then 1 else 0 end)
  • INNER JOIN гарантирует, что хотя бы 1 сотрудник
  • HAVING count(*) = sum(case when e.city = 'Barcelona' then 1 else 0 end) гарантирует, что все сотрудники из Барселоны
0 голосов
/ 29 сентября 2018

Присоединитесь к таблицам, сгруппируйте их по отделам и убедитесь, что количество сотрудников в Барселоне равно количеству всех сотрудников отдела.

SELECT d.dpt_num,
       d.dpt_name
       FROM departments d
            INNER JOIN employees e
                       ON e.dpt_num = d.dpt_num
       GROUP BY d.dpt_num,
                d.dpt_name
       HAVING count(CASE
                      WHEN e.city = 'Barcelona' THEN
                        1
                    END) = count(*);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...