Mogę zrobić SELECT TOP (200) ... ale dlaczego nie BOTTOM (200)?
Cóż, nie wchodząc w filozofię, mam na myśli to, jak mogę zrobić odpowiednik TOP (200), ale odwrotnie (od dołu, tak jak można by się spodziewać, że zrobi to BOTTOM ...)?
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
To jest niepotrzebne. Możesz użyć
ORDER BY
i po prostu zmienić sortowanie na,DESC
aby uzyskać ten sam efekt.źródło
Przepraszam, ale moim zdaniem nie widzę żadnych poprawnych odpowiedzi.
Funkcja
TOP
x wyświetla rekordy w nieokreślonej kolejności. Z tej definicji wynika, że aBOTTOM
funkcji nie można zdefiniować.Niezależnie od jakiegokolwiek indeksu lub porządku sortowania. Kiedy to zrobisz,
ORDER BY y DESC
najpierw otrzymasz wiersze z najwyższą wartością y. Jeśli jest to identyfikator wygenerowany automatycznie, powinien pokazywać rekordy ostatnio dodane do tabeli, jak sugerowano w innych odpowiedziach. Jednak:TOP
funkcją, ma to znaczący wpływ na wydajnośćPrawidłowa odpowiedź powinna być taka, że nie ma i nie może być odpowiednika
TOP
dla uzyskania najniższych wierszy.źródło
Logicznie
Np. Wybierz dolne 1000 od pracownika:
W T-SQL
źródło
Wydawałoby się, że którakolwiek z odpowiedzi, które implementują klauzulę ORDER BY w rozwiązaniu, nie ma sensu lub w rzeczywistości nie rozumie, co TOP Ci zwraca.
TOP zwraca nieuporządkowany zestaw wyników zapytania, który ogranicza zestaw rekordów do pierwszych N zwróconych rekordów. (Z punktu widzenia Oracle jest to podobne do dodania gdzie ROWNUM <(N + 1).
Każde rozwiązanie korzystające z zamówienia może zwrócić wiersze, które również są zwracane przez klauzulę TOP (ponieważ ten zbiór danych był w pierwszej kolejności nieuporządkowany), w zależności od kryteriów zastosowanych w zamówieniu przez
Użyteczność TOP polega na tym, że gdy zbiór danych osiągnie pewien rozmiar N, przestaje pobierać wiersze. Możesz zobaczyć, jak wyglądają dane, bez konieczności pobierania ich wszystkich.
Aby dokładnie zaimplementować BOTTOM, należałoby pobrać cały zestaw danych w nieuporządkowany sposób, a następnie ograniczyć go do ostatecznych N rekordów. Nie będzie to szczególnie skuteczne, jeśli masz do czynienia z dużymi stołami. Niekoniecznie też da ci to, co myślisz że prosisz. Koniec zbioru danych niekoniecznie musi oznaczać „ostatnie wstawione wiersze” (i prawdopodobnie nie będzie to miało miejsce w przypadku większości aplikacji intensywnie korzystających z DML).
Podobnie rozwiązania, które implementują ORDER BY są niestety potencjalnie katastrofalne w przypadku dużych zbiorów danych. Jeśli mam, powiedzmy, 10 miliardów rekordów i chcę ostatnich 10, to głupotą jest zamówienie 10 miliardów rekordów i wybranie ostatnich 10.
Problem polega na tym, że BOTTOM nie ma takiego znaczenia, o jakim myślimy , porównując go z TOP.
Kiedy rekordy są wstawiane, usuwane, wstawiane i usuwane w kółko, w pamięci pojawią się luki, a później wiersze zostaną wstawione, jeśli to możliwe. Ale to, co często widzimy, kiedy wybieramy TOP, wydaje się być posortowanymi danymi, ponieważ mogły zostać wstawione na początku istnienia tabeli. Jeśli w tabeli nie występuje wiele usunięć, może wydawać się, że jest uporządkowana. (np. daty utworzenia mogą być tak odległe w czasie, jak samo utworzenie tabeli). Ale rzeczywistość jest taka, że jeśli jest to tabela z dużą ilością usuwania, to TOP N wierszy może wcale tak nie wyglądać.
Tak więc - najważniejsze tutaj (gra słów zamierzona) jest to, że ktoś, kto prosi o nagrania BOTTOM N, tak naprawdę nie wie, o co proszą. A przynajmniej to, o co proszą i co właściwie oznacza DOLNY, nie jest tym samym.
A więc - rozwiązanie może spełniać rzeczywiste potrzeby biznesowe żądającego… ale nie spełnia kryteriów bycia DOLNYM.
źródło
insert
polecenie, aby umieścić wiersze w dużej, niezindeksowanej tabeli. (Najpierw zapełniam tabelę, zanim zacznę ją indeksować). Straciłem sesję klienta z powodu ponownego uruchomienia komputera lub czegoś innego, a teraz chcę sprawdzić, czy są tam moje nowo dodane wiersze. Jeśli „dolny” wiersz tabeli jest jednym z ostatnich, to wiem, że operacja została zakończona. Jeśli „dolny” wiersz jest czymś innym, cóż, nie ma żadnych gwarancji i muszę przeskanować całą tabelę, aby się upewnić ... ale najprawdopodobniej mógłbym zaoszczędzić trochę czasu, szybko sprawdzając „dół”, tak jak możesz. Top'.Aktualnie przyjęta odpowiedź przez „Justina Ethiera” nie jest poprawną odpowiedzią, jak wskazał „Protektor jeden”.
O ile widzę, na razie żadna inna odpowiedź ani komentarz nie jest odpowiednikiem BOTTOM (x), o które zadał autor pytania.
Najpierw rozważmy scenariusz, w którym ta funkcjonalność byłaby potrzebna:
Zwraca tabelę składającą się z jednej kolumny i pięciu rekordów:
Jak widać: nie mamy kolumny ID; nie możemy złożyć zamówienia według zwróconej kolumny; i nie możemy wybrać dwóch ostatnich rekordów za pomocą standardowego SQL, tak jak możemy to zrobić dla dwóch górnych rekordów.
Oto moja próba rozwiązania:
A oto bardziej kompletne rozwiązanie:
W żadnym wypadku nie twierdzę, że jest to dobry pomysł w każdych okolicznościach, ale zapewnia pożądane rezultaty.
źródło
Wszystko, co musisz zrobić, to odwrócić
ORDER BY
. Dodaj lub usuńDESC
do niego.źródło
Problem z kolejnością w drugą stronę polega na tym, że często nie wykorzystuje ona dobrze indeksów. Nie można go również zbytnio rozszerzać, jeśli kiedykolwiek zajdzie potrzeba wybrania liczby wierszy, które nie znajdują się na początku ani na końcu. Alternatywny sposób jest następujący.
źródło
Powyższa odpowiedź „Tom H” jest prawidłowa i działa w moim przypadku przy uzyskiwaniu 5 ostatnich wierszy.
Dzięki.
źródło
Spróbuj tego.
źródło
Wymyśliłem rozwiązanie tego problemu, które nie wymaga znajomości liczby zwróconych wierszy.
Na przykład, jeśli chcesz, aby wszystkie lokalizacje zostały zarejestrowane w tabeli, z wyjątkiem ostatniej 1 (lub 2 lub 5 lub 34)
źródło
Zapytanie o proste podzapytanie posortowane malejąco, a następnie sortowanie rosnąco na tej samej kolumnie załatwia sprawę.
źródło
Gdzie ID jest kluczem podstawowym tabeli TABLE1.
źródło
Najpierw utwórz indeks w podzapytaniu zgodnie z pierwotną kolejnością tabeli, używając:
Następnie uporządkuj tabelę malejąco według
RowIndex
kolumny utworzonej w głównym zapytaniu:I na koniec użyj
TOP
z żądaną liczbą rzędów:źródło