2013-07-06 32 views
18

Moje zapytanie:Eliminowanie zduplikowanych wartości w oparciu o tylko jednej kolumnie tabeli

SELECT sites.siteName, sites.siteIP, history.date 
FROM sites INNER JOIN 
    history ON sites.siteName = history.siteName 
ORDER BY siteName,date 

Pierwsza część wyjścia:

enter image description here

Jak mogę usunąć duplikaty w siteName kolumnie? Chcę zostawić tylko zaktualizowany na podstawie kolumny date.

W wyjściu powyższym przykładzie, muszę wiersze 1, 3, 6, 10

Odpowiedz

20

To gdzie funkcja okna row_number() przydaje:

SELECT s.siteName, s.siteIP, h.date 
FROM sites s INNER JOIN 
    (select h.*, row_number() over (partition by siteName order by date desc) as seqnum 
     from history h 
    ) h 
    ON s.siteName = h.siteName and seqnum = 1 
ORDER BY s.siteName, h.date 
+3

Czy mógłbyś nieco wyjaśnić zapytanie? – JacksOnF1re

+5

@ JacksOnF1re. . . Czy wiesz, co robi 'row_number()'? Wylicza wiersze w grupie (zdefiniowane przez klauzulę 'partition by'). Kolejność jest oparta na klauzuli 'order by'. Wybierając wartość 1, wybierany jest tylko jeden wiersz na grupę, i to będzie ten z największą datą. –

7

ze swojego przykład zasadne wydaje się załóżmy, że kolumna siteIP jest określona przez kolumnę siteName (to znaczy, że każda witryna ma tylko jedną siteIP). Jeśli tak jest w istocie, to istnieje proste rozwiązanie za pomocą group by:

select 
    sites.siteName, 
    sites.siteIP, 
    max(history.date) 
from sites 
inner join history on 
    sites.siteName=history.siteName 
group by 
    sites.siteName, 
    sites.siteIP 
order by 
    sites.siteName; 

Jednakże, jeśli moje założenie nie jest prawidłowe (czyli możliwe jest miejscem mieć wiele siteIP), to jest nie jest jasne, które pytanie należy wybrać, aby zapytanie powróciło w drugiej kolumnie. Jeśli tylko jakieś siteIP, wtedy następujące zapytanie zrobi:

select 
    sites.siteName, 
    min(sites.siteIP), 
    max(history.date) 
from sites 
inner join history on 
    sites.siteName=history.siteName 
group by 
    sites.siteName 
order by 
    sites.siteName;