Oracle SQL с использованием Distinct и Group By - PullRequest
0 голосов
/ 31 января 2019

У меня есть таблица ниже

+-----+------+-----------+------------+
| id  | type | last_name | first_name |
+-----+------+-----------+------------+
|   1 | A    | Billy     | John       |
|   2 | B    | Bob       | Joe        |
|   3 | A    | Joe       | Zeb        |
|   4 | C    | Billy     | John       |
| ... | ...  | ...       | ...        |
+-----+------+-----------+------------+

Я хочу вернуть все записи, которые имеют одинаковые LAST_NAME и FIRST_NAME, но имеют разные TYPE.

Нужно ли делать подзапрос, чтобы сначала получить те же имена, а затем отфильтровать его для TYPE?

Что я хотел бы вернуть:

+-----+------+-----------+------------+
| id  | type | last_name | first_name |
+-----+------+-----------+------------+
|   1 | A    | Billy     | John       |
|   4 | C    | Billy     | John       |
| ... | ...  | ...       | ...        |
+-----+------+-----------+------------+

Ответы [ 3 ]

0 голосов
/ 31 января 2019

возможно я что-то наблюдал.О чем вы думаете:

select * from table
group by last_name, first_name
having count(type) = 1
0 голосов
/ 31 января 2019

Это должно быть просто, используя оконные функции, которые доступны в Oracle с ранних версий:

SELECT x.id, x.type, x.last_name, x.first_name
FROM (
    SELECT t.*, COUNT(DISTINCT type) OVER (PARTITION BY last_name, first_name) cnt
    FROM mytable t
) x WHERE x.cnt > 1

Внутренний запрос назначает каждой записи количество различных типов для текущего кортежа имени / фамилии,и внешний запрос выводит строки со счетчиком 1.

Демонстрация на DB Fiddle :

ID | TYPE | LAST_NAME | FIRST_NAME
-: | :--- | :-------- | :---------
 1 | A    | Billy     | John      
 4 | C    | Billy     | John      
0 голосов
/ 31 января 2019

Вот один из возможных способов использования коррелированного подзапроса:

select t.*
from table1 t
where exists 
(
    select 1 from table1 u
    where 
    u.last_name = t.last_name and 
    u.first_name = t.first_name and 
    u.type <> t.type
)

Или, возможно, использование объединений:

select t.*
from table1 t inner join
(
    select u.last_name, u.first_name
    from table1 u
    group by u.last_name, u.first_name
    having min(u.type) <> max(u.type)
) q 
on t.last_name = q.last_name and t.first_name = q.first_name

Измените table1 в соответствии с именем таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...