2009-11-09 9 views
7

Próbuję utworzyć zapytanie, które wyświetli jeden określony rekord (znaleziony przez podstawowy identyfikator rekordu) u góry i wyświetlić wszystkie pozostałe wpisy poniżej, posortowane według daty (mam "date_added" jako jedno z pól w tabeli, oprócz podstawowego ID).SQL, aby mieć jeden określony rekord na górze, wszystkie inne poniżej

Mógłbym to zrobić z UNION (pierwszy wybrałbym zlokalizować rekord, który chcę, a drugi wybrałby wyświetlić wszystkie inne rekordy), ale zastanawiam się, czy jest może lepszy sposób?

Używam Oracle, przy okazji.

Odpowiedz

17

Można to zrobić poprzez sortowanie według dwóch pól

Pierwszy byłoby wyrażenie, które zwraca 0, jeśli wiersz jest jeden chcesz lub 1 jeśli nieprawdaż "t. Sortowanie będzie rosnąć, więc najpierw uzyskasz preferowaną pozycję.

Drugie pole sortowania zostanie zmienione na date_added, więc pozostałe rekordy zostaną posortowane w tej kolejności.

boi nie wiem wyrocznię przez serwer sql byłoby to coś jak

select * 
from the_table 
order by (case id when 999 then 0 else 1 end), date_added desc 
+0

Dzięki za odpowiedź. Co, nawiasem mówiąc, oznacza "zamówienie przez 0"? Zauważyłem, że nie mogę używać tego samodzielnie, np. tylko "ZAMÓW PRZEZ 0". (Otrzymuję błąd: "ORDER BY item musi być numerem wyrażenia listy SELECT") – Dario

+1

'ORDER BY ' ma specjalne znaczenie w Oracle, będzie sortować na n-tej kolumnie. Oczywiście nigdy nie ma kolumny 0. W przypadku CASE, doda on nową kolumnę do każdego wiersza i posortuje ją. Nowa kolumna będzie 1 dla pasującego klucza podstawowego i 0 wszędzie indziej. – Andomar

1

nie wiem Oracle dokładnie, ale można chyba zrobić coś takiego ..

ORDER BY IF(id == THE_ID, 0, 1), date_added 
+0

+1 Nie jestem pewien, czy Oracle wspiera IF w ten sposób! – Andomar

+0

Oracle nie obsługuje IIF, ale możesz "DECODE (id, THE_ID, 0,1)" zamiast tego – Andomar

7

Łatwiejszy sposób byłoby to wyszukane zamówienie przez konstruktu. Oto przykład dla pk = 123:

select * 
from YourTable 
order by case when yourpk = 123 then 1 else 2 end, date_added 
+0

to by umieścić konkretny rekord na końcu, powinno być "... potem 1 else 2 koniec ..." –

+0

@ammoQ: Dzięki, odpowiedź edytowana (reko_t opublikował ten sam pomysł wcześniej tho) – Andomar

-1

Prostym sposobem byłoby uznać, że chcesz wyświetlić dwie odrębne rzeczy, a więc napisać do oddzielenia prostych zapytań. Jedno zapytanie do pobrania pierwszego rekordu, a drugie do pobrania posortowanej listy. Nie ma żadnej realnej przewagi nad robieniem czegokolwiek więcej, z powodu jednego wyjątkowego rekordu.

+0

Tak, ale istnieją zalety robienia tego jako pojedynczego polecenia SQL. Niektóre środowiska (na przykład zestawy raportów) nie pozwalają na łatwe ponowne użycie konstrukcji SQL, więc może on dwukrotnie powtórzyć większość kodu SQL, co jest problematyczne z powodu konserwacji. Również robienie tego w SQL jest bardziej spójne :-). – sleske

0
SELECT * 
FROM `Table` 
ORDER BY (`id` = THE_ID) DESC, `date_added` DESC 
0

można sortować więcej niż jeden rekord na górę tą samą techniką

999 pierwszy 998 sekund następnie wszystko inne posortowane według daty

select *

from the_table 
order by (case id when 999 then 0 when 998 then 1 else 2 end), date_added desc 
Powiązane problemy