简体   繁体   中英

Oracle SQL using Distinct and Group By

I've a table below

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

I want to return all records that has the same LAST_NAME and FIRST_NAME , but have different TYPE .

Would I need to do a subquery to first get the same names, then to filter it for the TYPE ?

What I would like to return:

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

Here is one possible method using a correlated subquery:

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
)

Or, perhaps using joins:

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

Change table1 to suit your table name.

maybe I have overseen something. What do you think about:

select * from table
group by last_name, first_name
having count(type) = 1

This should be straightforward using window functions, which are available in Oracle since early versions :

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

The inner query assigns to each record a count of distinct types for the current first/last name tuple, and the outer query fiters out rows with a count of 1.

Demo on DB Fiddle :

ID | TYPE | LAST_NAME | FIRST_NAME
-: | :--- | :-------- | :---------
 1 | A    | Billy     | John      
 4 | C    | Billy     | John

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM