/ / DISTINCT wyciągając zduplikowane wartości kolumn - sql, złącz, wyraźne, łączenie wewnętrzne

DISTINCT pobierające wartości z podwójnych kolumn - sql, join, distinct, inner-join

Następujące zapytanie pobiera duplikat site_ids, ze mną używając DISTINCT, nie mogę zrozumieć, dlaczego ...

SELECT
DISTINCT site_id,
deal_woot.*,
site.woot_off,
site.name AS site_name
FROM deal_woot
INNER JOIN site ON site.id = site_id
WHERE site_id IN (2, 3, 4, 5, 6)
ORDER BY deal_woot.id DESC LIMIT 5

Odpowiedzi:

2 dla odpowiedzi № 1

DISTINCT patrzy na Cały nagrywać, nie tylko kolumnę bezpośrednio za nią. Aby osiągnąć to, czego chcesz, musisz użyć GROUP BY:

Niedziałający kod:

SELECT
site_id,
deal_woot.*,
site.woot_off,
site.name AS site_name
FROM deal_woot
INNER JOIN site ON site.id = site_id
WHERE site_id IN (2, 3, 4, 5, 6)
GROUP BY site_id

Dlaczego to nie działa? GROUP BY kolumna, należy użyć funkcji agregującej (takiej jak MIN lub MAX) w pozostałych kolumnach - w przeciwnym razie, jeśli jest ich wiele site_woot_offs dla danego site_id, nie jest jasne dla SQL która z tych wartości chcesz SELECT.

Prawdopodobnie będziesz musiał się rozwinąć deal_woot.* aby wyświetlić listę każdego z jego pól.

Dygresja: Jeśli używasz MySQL, uważam, że nie jest technicznie konieczne określanie funkcji agregującej dla pozostałych kolumn. Jeśli nie określisz funkcji agregującej dla kolumny, wybierze ona dla ciebie wartość pojedynczej kolumny (zazwyczaj pierwszą wartość w zestawie wyników).


2 dla odpowiedzi nr 2

Twoje zapytanie powraca DISTINCT wiersze, to nie tylko patrzenie site_id. Innymi słowy, jeśli którakolwiek z kolumn jest inna, zwracany jest nowy wiersz z tego zapytania.

Ma to sens, ponieważ jeśli faktycznie masz różnice, to co serwer powinien zwrócić jako wartości deal_woot.* ? Jeśli chcesz to zrobić, musisz to określić - być może zrobisz to, wyróżniając się site_id„s, a następnie dostaniesz LIMIT 1 innych wartości w podzapytaniu z odpowiednim ORDER BY klauzula.


0 dla odpowiedzi № 3

Wybieracie odrębną wartość tylko z jednej tabeli. Kiedy połączysz się z drugą tabelą, pociągnie ona wszystkie wiersze, które pasują do każdej twojej odrębnej wartości z drugiej tabeli, powodując zduplikowane identyfikatory


0 dla odpowiedzi nr 4

Jeśli chcesz wybrać informacje o witrynie i pojedynczy wiersz z tabeli deal_woot o tym samym identyfikatorze strony, musisz użyć innego zapytania. Na przykład,

SELECT site.id, deal_woot.*, site.woot_off, site.name
FROM site
INNER JOIN
(SELECT site_id, MAX(id) as id FROM deal_woot
WHERE site_id IN (2,3,4,5,6) GROUP BY site_id) X
ON (X.site_id = site.id)
INNER JOIN deal_woot ON (deal_woot.id = X.id)
WHERE site.id IN (2,3,4,5,6);

To zapytanie powinno działać niezależnie od dostawcy dialektu / db sql. W przypadku mysql możesz po prostu dodać group by site_id do oryginalnego zapytania, ponieważ pozwala ono na użycie GROUP BY bez funkcji agregujących.
** Zakładam, że deal_woot.id i site.id są kluczami podstawowymi dla deal_woot i site tabele odpowiednio.