29

Suppose I have a SQL table "Celebrities" with two columns: "fname" and "lname":

fname    | lname    
---------+-------  
Bill     | Clinton
Bill     | Gates
George   | Bush
George   | Clinton
Barack   | Obama

I would like to write a query that returns the first and last name of each person in the table whose last name appears at least twice in the column "lname". How do I write this SQL query?

Vivian River
  • 31,198
  • 62
  • 198
  • 313

3 Answers3

69
SELECT fname, lname FROM Celebrities 
WHERE lname IN 
 (SELECT lname FROM Celebrities 
  GROUP BY lname HAVING COUNT (lname) >1)
Ocaso Protal
  • 19,362
  • 8
  • 76
  • 83
11

Using a JOIN:

SELECT a.*
  FROM CELEBRITIES a
  JOIN (SELECT c.lname
          FROM CELEBRITIES c
      GROUP BY c.lname
        HAVING COUNT(*) >= 2) b ON b.lname = a.lname

Using EXISTS:

SELECT a.*
  FROM CELEBRITIES a
 WHERE EXISTS (SELECT NULL
                 FROM CELEBRITIES c
                WHERE c.lname = a.lname
             GROUP BY c.lname
               HAVING COUNT(*) >= 2) 
OMG Ponies
  • 325,700
  • 82
  • 523
  • 502
  • 3
    A small performance note: I found the EXISTS method to be the fastest, then the JOIN method, and in a distant third the IN method. Also: having an index on the counted column (lname) is a big help too. – Nathan Colgate Apr 03 '13 at 21:44
3
select fname, lname
from 
  (
    select fname, lname, count(*) over(partition by lname) as lcount
    from Celebrities
  ) as S
where lcount > 1

Tested in SQL Server 2008. Might work in other DBMS that support count(*) over(...)

Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281