2011-09-16 17 views
5

Mam tabelę z wieloma wierszami, które mają takie same dane. Użyłem SELECT DISTINCT, aby uzyskać unikalny wiersz i działa dobrze. Ale kiedy używam ORDER BY z SELECT DISTINCT, daje mi to nieposortowane dane.Jak działa SELECT DISTINCT w MySQL?

Czy ktoś może mi powiedzieć, jak różne prace?

Na podstawie jakich kryteriów wybiera wiersz?

+0

Jakie są zapytania, które próbujesz uruchomić? – srivani

+0

@srivani: Wybierz wyraźny identyfikator z tabeli, gdzie id2 = 12312 porządek według czasu. – insomiac

+0

Wiem, że jest już za późno, ale nie ma jeszcze zaakceptowanej odpowiedzi, więc chcę się dowiedzieć, czy OP nadal chce odpowiedzi na coś, czego nie obejmują podane odpowiedzi? –

Odpowiedz

1

Po określeniu SELECT DISTINCT otrzymasz wszystkie wiersze, eliminując duplikaty ze zbioru wyników. Przez "duplikaty" mam na myśli wiersze, w których wszystkie pola mają te same wartości. Załóżmy, że mamy tabelę, która wygląda tak:

id | num 
-------------- 
1 | 1 
2 | 3 
3 | 3 

SELECT DISTINCT * wróci wszystkie wiersze powyżej, natomiast SELECT DISTINCT num wróci dwa rzędy:

num 
----- 
1 
3 

pamiętać, że który wiersz rzeczywisty rząd (np: czy to wiersz 2 lub wiersz 3), który wybiera, jest nieistotny, ponieważ rezultat byłby nie do odróżnienia.

Wreszcie powinien nie wpływa na to, jak działa ORDER BY.

referencyjny: MySQL SELECT statement

+2

Wygląda na to, że działa w MYSQL. Przeczytaj: http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html – Icarus

+0

to prawie jak błąd :) – Randy

+0

@Icarus Jakie optymalizacje wykonuje nie ma znaczenia, tak długo jak zestaw wyników wraca tak, jak tego oczekujesz. – NullUserException

2

Od komentarz wcześniej, zapytanie próbujesz uruchomić to

Select distinct id from table where id2 =12312 order by time desc. 

Jak oczekiwano, tu jest twój problem. Twoja wybrana kolumna i kolejność według kolumn są różne. Twoje wyjściowe wiersze są uporządkowane według czasu, ale kolejność ta niekoniecznie musi być zachowana w kolumnie id. Oto przykład.

id | id2 | time 
------------------- 
1 | 12312 | 34 
2 | 12312 | 12 
3 | 12312 | 48 

Jeśli prowadzisz

SELECT * FROM table WHERE id2=12312 ORDER BY time DESC 

otrzymasz następujący wynik

id | id2 | time 
------------------- 
2 | 12312 | 12 
1 | 12312 | 34 
3 | 12312 | 48 

Teraz, jeśli wybrać tylko kolumnę id z tego, dostaniesz

id 
-- 
2 
1 
3 

Oto dlaczego masz wyniki nie posortowane.

+0

Co jeśli masz wiele identyfikatorów (np. Id = 2 i id = 1 wielokrotnie), który z nich wybierze, wykonując desc według czasu? – insomiac

+0

Po uruchomieniu opcji "Wybierz oddzielny identyfikator z tabeli, w której id2 = 12312 porządek według czasu", duplikaty zostaną usunięte. Jeśli uruchomisz "Wybierz identyfikator z tabeli, gdzie id2 = 12312 porządek według czasu", wyniki będą zawierać duplikaty. Wszystkie wystąpienia identyfikatora zostaną zwrócone. – srivani

+0

dziękuję za odpowiedź, Na przykład, jeśli chcę uzyskać najnowsze identyfikatory jak na czas i jeśli robię desc przez czas z wyraźnym id. Nie działa z mysql. Czy wiesz, jak wyróżnia się dzieła według kolejności? – insomiac

0

Zachowanie, które opisujesz, dzieje się, gdy ORDER BY wyrażenie, które nie występuje w klauzuli SELECT. Standard SQL nie dopuszcza takiego zapytania, ale MySQL jest mniej ścisły i pozwala na to.

Spróbujmy przykład:

SELECT DISTINCT colum1, column2 
FROM table1 
WHERE ... 
ORDER BY column3 

Powiedzmy zawartość tabeli table1 jest:

id | column1 | column2 | column3 
----+---------+---------+--------- 
    1 | A  | B  | 1 
    2 | A  | B  | 5 
    3 | X  | Y  | 3 

Bez klauzuli ORDER BY powyższe zwroty kwerendy następujące dwa rekordy (bez ORDER BY kolejność nie jest gwarantowane):

column1 | column2 
---------+--------- 
A  | B 
X  | Y 

Ale z ORDER BY column3 zamówienie również nie jest gwarantowane.

Klauzula DISTINCT działa na wartości wyrażeń obecnych w klauzuli SELECT. Jeśli wiersz nr 1 jest przetwarzany jako pierwszy, wówczas (A, B) zostaje umieszczony w zestawie wyników i jest powiązany z wierszem nr 1. Następnie, gdy przetwarzany jest wiersz nr 2, wartości wyrażeń SELECT generują rekord (A, B), który już znajduje się w zestawie wyników. Z powodu DISTINCT jest on upuszczany. Wiersz nr 3 produkuje (X, Y), który jest również umieszczany w zestawie wyników. Następnie klauzula ORDER BY column3 powoduje, że rekordy są sortowane w zestawie wyników jako (A, B), (X, Y).

Ale jeśli rząd nr 2 jest przetwarzany przed rzędu # 1 następnie, zgodnie z tą samą logiką odsłoniętą w poprzednim akapicie, zapisy w zestawie wyników są klasyfikowane jako (X, Y), (A, B).

Na silniku bazy danych nie obowiązuje żadna reguła dotycząca kolejności przetwarzania wierszy podczas uruchamiania kwerendy. Baza danych może przetwarzać wiersze w dowolnej kolejności, którą uważa za lepszą pod względem wydajności.

Twoje zapytanie jest nieprawidłowe. Potwierdza to fakt, że może zwracać różne wyniki przy użyciu tych samych danych wejściowych.