Czy możesz nam powiedzieć, w jakiej kolejności chcesz znaleźć się na pierwszej pozycji?
Andrew Wolfe
1
Po pierwsze, nigdy nie powinieneś nigdy polegać na silniku DB. Jeśli chcesz wiedzieć takie rzeczy, włóż sekwencer. Gdy to zrobisz, gwarantuje się, że będą one ponumerowane w kolejności, w jakiej zostały wstawione.
Jest to dobre, jeśli chcesz tylko 1 wiersz i nie przejmuj się, które. Jeśli chcesz konkretnych wierszy, takich jak najnowszy rekord, musisz wykonać sortowanie w podselekcji, na przykład odpowiedź Vasha. Oracle przydziela rownum przed sortowaniem.
Scott Bailey,
4
@Scott yup. to jest poprawne. I Patrick, uważam, że składnia jest nieprawidłowa. To naprawdę powinno być utrzymanie (dense_rank () last ...)
mcpeterson
2
Różnica między pierwszym a drugim przykładem polega na tym, że pierwszy wybiera wiersz A (dowolny wiersz, bez kolejności). Drugi przykład pobiera wartość pierwszego wiersza bez wykonywania wewnętrznego zapytania dotyczącego kolejności (jak w przykładach poniżej).
JulesLt,
3
Składnia niepoprawna w: wybierz max (fname) ponad (rank () sortuj według some_factor) z MyTbl
Stéphane Gerber
1
@ jclozano „niezbyt dobrze znana funkcjonalność wyroczni” - Z szacunkiem zaczynam się różnić. Ma to znaczenie, ponieważ „mało znana funkcjonalność” zwykle sugeruje niejasność i dlatego może sugerować, że powinniśmy unikać używania. Nie jest to niejasne i nie należy go unikać.
Ciekawe polecenie, używam tutaj 12c i OFFSET 0 ROWSnajwyraźniej nie jest to konieczne, możesz użyć, FETCH NEXT 1 ROWS ONLYa nawet FETCH FIRST ROW ONLY, kolejność według jest ważna lub będzie równoważna z samym użyciem WHERE rownum = 1. Próbowałem nawet w instrukcji OUTER APPLY i działało to jak funkcja TOP Ms-SQL.
Rafael Merlin,
Masz rację @RafaelMerlin. Po twoim poście uznałem, że OFFSET 0 ROWS nie jest konieczny. Przydałoby się to przy pobieraniu danych między górnym X a górnym Y.
Jak dotąd tak dobrze, z ważnym brakującym punktem TIES. Odnosi się to do przypadków, w których występują powiązania dla wersji 12c +i12c -
Barbaros Özhan
10
Możesz użyć ROW_NUMBER()z ORDER BYklauzulą w zapytaniu podrzędnym i użyć tej kolumny zamiast TOP N. Można to wyjaśnić krok po kroku.
Zobacz poniższą tabelę, która ma dwie kolumny NAMEi DT_CREATED.
Jeśli potrzebujesz wziąć tylko dwie pierwsze daty, niezależnie od tego NAME, możesz użyć poniższego zapytania. Logika została zapisana w zapytaniu
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(-- Generates numbers in a column in sequence in the order of dateSELECT ROW_NUMBER()OVER(ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
WYNIK
W niektórych sytuacjach musimy wybrać TOP Nwyniki dla każdego z nich NAME. W takim przypadku możemy użyć PARTITION BYz ORDER BYklauzulą w zapytaniu podrzędnym. Zobacz poniższe zapytanie.
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(--Generates numbers in a column in sequence in the order of date for each NAMESELECT ROW_NUMBER()OVER(PARTITIONBY NAME ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
Użycie ROW_NUMBER () ... jest bardziej poprawnym rozwiązaniem niż w temacie odpowiedzi. Jeden problem z tym rozwiązaniem (a także z wariantem maks. (Polowym)) polegający na tym, że nie można robić takich rzeczy jak „wybierz ... (wybierz ROW_NUMBER () ...) do aktualizacji ;”
Alexo Po.
I czasami jest to bardzo ważne w PL / SQL (przepraszam, nie edytowałem poprzedniego komentarza w ciągu 5 minut).
Alexo Po.
W takim przypadku możemy użyć CTE jak w części zewnętrznej. Dobrze? @Alexo Po.
Sarath Avanavu
Myślę, że cię nie rozumiem. klauzula aktualizacji może być używana, gdy ROWID jest „łatwo” zachowany przez Oracle. Tak więc grupowanie (i grupowanie z powodu użycia klauzul analitycznych) ukrywa prawdziwy ROWID i wierszy nie można zablokować. Po drugie, CTE ( with (select ... ) as klauzula) nic nie zmienia w tym problemie, CTE po prostu ma na celu czytanie i wspieranie zapytań. Dobrze? @Sarath Avanavu
Alexo Po.
Uwaga na siebie. Problem z ROWID faktycznie dzieje się szczególnie ze względu na to, gdzie warunek RNO <3 , w tym przypadku wartość RNO nie jest powiązana z ROWID, dlatego Oracle nie może blokować wierszy.
Alexo Po.
9
Możesz zrobić coś takiego
SELECT*FROM(SELECT Fname FROM MyTbl ORDERBY Fname )WHERE rownum =1;
Można również skorzystać z funkcji analitycznych RANK i / lub DENSE_RANK , ale ROWNUM jest chyba najprostszy.
@carpenteri: To prawda, że analityka była dostępna w 8i - nie pamiętam szczegółów, ale analityka nie była tak naprawdę publicznie dostępna do 9i.
OMG Kucyki
Mały komentarz - poniższa odpowiedź Vash zawiera ORDER BY w wewnętrznym zapytaniu, co jest krytyczne, jeśli chcesz NAJLEPSZĄ wartość fname, a nie „first” (która może być dowolna, najprawdopodobniej wstawiony pierwszy wiersz). Może warto edytować?
JulesLt,
@JulesLt: Kwerenda dostarczona przez OP nie zawiera ORDER BY, więc jest to odpowiedź i dokładne tłumaczenie na składnię Oracle.
Kucyki OMG,
Moje nieporozumienie dotyczące składni SQL SERVER TOP (błędnie zakładałem, że było podobne do FIRST w RANK, a nie ROWNUM). Zagłosowano.
JulesLt,
3
Aby wybrać pierwszy wiersz z tabeli i wybrać jeden wiersz z tabeli, są dwa różne zadania i wymagają innego zapytania. Można to zrobić na wiele sposobów. Cztery z nich to:
Pierwszy
select max(Fname)from MyTbl;
druga
select min(Fname)from MyTbl;
Trzeci
select Fname from MyTbl where rownum =1;
Czwarty
select max(Fname)from MyTbl where rowid=(select max(rowid)from MyTbl)
Odpowiedzi:
Jeśli chcesz tylko pierwszy wybrany wiersz, możesz:
Możesz także użyć funkcji analitycznych, aby zamówić i wziąć górę x:
źródło
źródło
top X
jednego można to zmienić naWHERE ROWNUM <= X
Dzięki Oracle 12c (czerwiec 2013 r.) Możesz używać jej w następujący sposób.
źródło
OFFSET 0 ROWS
najwyraźniej nie jest to konieczne, możesz użyć,FETCH NEXT 1 ROWS ONLY
a nawetFETCH FIRST ROW ONLY
, kolejność według jest ważna lub będzie równoważna z samym użyciemWHERE rownum = 1
. Próbowałem nawet w instrukcji OUTER APPLY i działało to jak funkcja TOP Ms-SQL.TIES
. Odnosi się to do przypadków, w których występują powiązania dla wersji12c +
i12c -
Możesz użyć
ROW_NUMBER()
zORDER BY
klauzulą w zapytaniu podrzędnym i użyć tej kolumny zamiastTOP N
. Można to wyjaśnić krok po kroku.Zobacz poniższą tabelę, która ma dwie kolumny
NAME
iDT_CREATED
.Jeśli potrzebujesz wziąć tylko dwie pierwsze daty, niezależnie od tego
NAME
, możesz użyć poniższego zapytania. Logika została zapisana w zapytaniuWYNIK
W niektórych sytuacjach musimy wybrać
TOP N
wyniki dla każdego z nichNAME
. W takim przypadku możemy użyćPARTITION BY
zORDER BY
klauzulą w zapytaniu podrzędnym. Zobacz poniższe zapytanie.WYNIK
źródło
with (select ... ) as
klauzula) nic nie zmienia w tym problemie, CTE po prostu ma na celu czytanie i wspieranie zapytań. Dobrze? @Sarath AvanavuMożesz zrobić coś takiego
Można również skorzystać z funkcji analitycznych RANK i / lub DENSE_RANK , ale ROWNUM jest chyba najprostszy.
źródło
źródło
Posługiwać się:
Jeśli używasz Oracle9i +, możesz spojrzeć na użycie funkcji analitycznych takich jak ROW_NUMBER (), ale nie będą one działały tak dobrze, jak ROWNUM .
źródło
Aby wybrać pierwszy wiersz z tabeli i wybrać jeden wiersz z tabeli, są dwa różne zadania i wymagają innego zapytania. Można to zrobić na wiele sposobów. Cztery z nich to:
Pierwszy
druga
Trzeci
Czwarty
źródło
Miałem ten sam problem i mogę to naprawić za pomocą tego rozwiązania:
Możesz zamówić swój wynik wcześniej, aby mieć pierwszą wartość na górze.
Powodzenia
źródło