Chciałbym poznać niektóre (idealnie) agnostyczne sposoby wybierania n- tego wiersza z tabeli bazy danych. Interesujące byłoby również zobaczyć, jak można to osiągnąć za pomocą natywnej funkcjonalności następujących baz danych:
- SQL Server
- MySQL
- PostgreSQL
- SQLite
- Wyrocznia
Obecnie robię coś podobnego do SQL Server 2005, ale chciałbym zobaczyć bardziej agnostyczne podejście innych:
WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000
Podziękowania za powyższy SQL: blog internetowy Firoz Ansari
Aktualizacja: Zobacz odpowiedź Troelsa Arvina dotycząca standardu SQL. Troels, czy masz jakieś linki, które możemy zacytować?
OrderNo N
, wprowadź kolumnę OrderSequenceNo w tabeli i wygeneruj ją z niezależnego generatora sekwencji po utworzeniu nowego zamówienia.offset x fetch first y rows only
. Obecnie obsługiwany przez (przynajmniej) Postgres, Oracle12, DB2.Odpowiedzi:
Można to zrobić w opcjonalnych częściach standardu, ale wiele baz danych obsługuje ich własny sposób.
Naprawdę dobra strona, która mówi o tym i innych rzeczach to http://troels.arvin.dk/db/rdbms/#select-limit .
Zasadniczo PostgreSQL i MySQL obsługują niestandardowe:
Oracle, DB2 i MSSQL obsługuje standardowe funkcje okienkowania:
(które właśnie skopiowałem ze strony, do której prowadzi link, ponieważ nigdy nie używam tych baz danych)
Aktualizacja: Począwszy od PostgreSQL 8.4, obsługiwane są standardowe funkcje okienkowania, więc spodziewaj się, że drugi przykład zadziała również dla PostgreSQL.
Aktualizacja: SQLite dodał obsługę funkcji okna w wersji 3.25.0 w dniu 15.09.2018, więc obie formy działają również w SQLite.
źródło
WHERE rownumber = n
tylko n-tego rzędu?PostgreSQL obsługuje funkcje okienkowania zdefiniowane w standardzie SQL, ale są one niewygodne, więc większość ludzi używa (niestandardowych)
LIMIT
/OFFSET
:W tym przykładzie wybrano 21 wiersz.
OFFSET 20
nakazuje Postgresowi pominięcie pierwszych 20 rekordów. Jeśli nie określiszORDER BY
klauzuli, nie ma gwarancji, który rekord otrzymasz, co jest rzadko przydatne.źródło
Nie jestem pewien co do reszty, ale wiem, że SQLite i MySQL nie mają żadnej „domyślnej” kolejności wierszy. Przynajmniej w tych dwóch dialektach następujący fragment pobiera 15. pozycję z tabeli, sortując według daty / godziny, w której został dodany:
(oczywiście musisz mieć dodane pole DATETIME i ustawić je na datę / czas dodania wpisu ...)
źródło
SQL 2005 i nowsze wersje mają tę wbudowaną funkcję. Użyj funkcji ROW_NUMBER (). Doskonale nadaje się do stron internetowych z przeglądaniem w stylu << Poprzednie i Następne >>:
Składnia:
źródło
Podejrzewam, że jest to niezwykle nieefektywne, ale jest dość prostym podejściem, które działało na małym zestawie danych, na którym wypróbowałem.
To otrzyma piąty przedmiot, zmień drugi najwyższy numer, aby uzyskać inny n-ty przedmiot
Tylko serwer SQL (tak myślę), ale powinien działać na starszych wersjach, które nie obsługują ROW_NUMBER ().
źródło
1 mała zmiana: n-1 zamiast n.
źródło
Sprawdź to na serwerze SQL:
To da ci 10-ty RZĘD tabeli emp!
źródło
W przeciwieństwie do tego, co twierdzą niektóre odpowiedzi, standard SQL nie milczy na ten temat.
Od SQL: 2003 można używać „funkcji okna” do pomijania wierszy i ograniczania zestawów wyników.
W SQL: 2008 dodano nieco prostsze podejście, używając
OFFSET skip ROWS FETCH FIRST n ROWS ONLY
Osobiście nie sądzę, aby dodatek SQL: 2008 był naprawdę potrzebny, więc gdybym był ISO, trzymałbym go poza dość dużym standardem.
źródło
Kiedy pracowaliśmy w MSSQL 2000, robiliśmy to, co nazywaliśmy „triple-flip”:
EDYTOWANE
Nie był elegancki i nie był szybki, ale działał.
źródło
IF / ELSE IF
bloki poniżejOuterPageSize
obliczeń - na stronach 1 i 2OuterPageSize
wartość spadnie z powrotem do 10. Na stronie 3 (wiersze 21–25) obliczenia zwrócą poprawnie 5, a na wszystkich stronach 4 i wyższych, wynik ujemny z obliczeń zostanie zastąpiony przez 0 (choć prawdopodobnie natychmiast byłoby natychmiast zwrócić pusty wiersz danych w tym momencie).Wybierz n-ty rekord od góry
wybierz n-ty rekord od dołu
źródło
Wyrocznia:
źródło
where ROWNUM = x
będzie działać tylko dla x = 1 w Oracle DB. tzn.where ROWNUM = 2
nie zwróci żadnych wierszy.W Oracle 12c możesz użyć
OFFSET..FETCH..ROWS
opcji zORDER BY
Na przykład, aby uzyskać trzeci rekord od góry:
źródło
Oto szybkie rozwiązanie twojego zamieszania.
Tutaj możesz uzyskać ostatni wiersz, wypełniając N = 0, drugi ostatni przez N = 1, czwarty ostatni, wypełniając N = 3 i tak dalej.
To bardzo częste pytanie w trakcie wywiadu i jest to bardzo prosta odpowiedź.
Ponadto, jeśli chcesz Kwota, identyfikator lub jakieś porządek sortowania numerycznego, możesz przejść do funkcji CAST w MySQL.
Tutaj, wypełniając N = 4, będziesz mógł zdobyć Piąty ostatni rekord najwyższej kwoty z tabeli KOSZYK. Możesz dopasować nazwę pola i tabeli i znaleźć rozwiązanie.
źródło
DODAJ:
To ograniczy wyniki do jednego wyniku, zaczynając od wyniku n.
źródło
Na przykład, jeśli chcesz wybierać co 10 wiersz w MSSQL, możesz użyć;
Po prostu weź MOD i zmień tutaj liczbę 10 na dowolną.
źródło
W przypadku SQL Server ogólny sposób na przejście według numeru wiersza jest taki:
Na przykład:
Zwróci to informację o 20 rzędzie. Pamiętaj, aby później wpisać 0
źródło
LIMIT n, 1 nie działa w MS SQL Server. Myślę, że chodzi tylko o jedyną dużą bazę danych, która nie obsługuje tej składni. Szczerze mówiąc, nie jest to część standardu SQL, chociaż jest tak szeroko wspierana, że powinna. We wszystkim oprócz SQL Server LIMIT działa świetnie. W przypadku serwera SQL nie udało mi się znaleźć eleganckiego rozwiązania.
źródło
Oto ogólna wersja sproca, który niedawno napisałem dla Oracle, która umożliwia dynamiczne stronicowanie / sortowanie - HTH
źródło
Ale tak naprawdę, czy to nie są naprawdę tylko sztuczki dla dobrego projektu bazy danych? Kilka razy potrzebowałem takiej funkcjonalności, żeby zrobić proste, jednorazowe zapytanie, aby zrobić szybki raport. Przy każdej prawdziwej pracy używanie takich sztuczek jest zapraszaniem do kłopotów. Jeśli konieczne jest wybranie określonego wiersza, wystarczy mieć kolumnę o wartości sekwencyjnej i wykonać to.
źródło
W przypadku serwera SQL poniższe polecenie zwróci pierwszy wiersz z podanej tabeli.
Możesz przeglądać wartości za pomocą czegoś takiego:
źródło
W Sybase SQL Anywhere:
Nie zapomnij ORDER BY lub jest to bez znaczenia.
źródło
T-SQL - Wybieranie N-tego rekordu z tabeli
Na przykład, aby wybrać 5. rekord z tabeli Pracownik, twoje zapytanie powinno być
źródło
źródło
Napisałem to zapytanie, aby znaleźć N-ty wiersz. Przykładem tego zapytania byłoby
źródło
niewiarygodne, że można znaleźć silnik SQL wykonujący ten ...
źródło
Nic szczególnego, żadnych specjalnych funkcji, na wypadek, gdybyś używał Caché tak jak ja ...
Biorąc pod uwagę, że masz kolumnę identyfikatora lub kolumnę datestamp, której możesz zaufać.
źródło
W ten sposób zrobiłbym to w programie DB2 SQL. Sądzę, że RRN (względny numer rekordu) jest przechowywany w tabeli przez O / S;
źródło
Najpierw wybierz 100 najlepszych wierszy, sortując rosnąco, a następnie wybierz ostatni wiersz, sortując malejąco i ogranicz do 1. Jednak jest to bardzo kosztowne stwierdzenie, ponieważ dwukrotnie uzyskuje dostęp do danych.
źródło
Wydaje mi się, że aby być wydajnym, musisz 1) wygenerować losową liczbę od 0 do jeden mniejszą niż liczba rekordów bazy danych, i 2) być w stanie wybrać wiersz w tej pozycji. Niestety różne bazy danych mają różne generatory liczb losowych i różne sposoby wyboru wiersza w pozycji w zestawie wyników - zwykle określa się liczbę wierszy do pominięcia i liczbę wierszy, ale robi się inaczej dla różnych baz danych. Oto coś, co działa dla mnie w SQLite:
Zależy to od możliwości zastosowania podzapytania w klauzuli limitu (która w SQLite to LIMIT <recs to skip>, <recs to take>) Wybór liczby rekordów w tabeli powinien być szczególnie wydajny, ponieważ jest częścią bazy danych metadane, ale zależy to od implementacji bazy danych. Ponadto nie wiem, czy zapytanie faktycznie zbuduje zestaw wyników przed pobraniem N-tego rekordu, ale mam nadzieję, że nie będzie to konieczne. Pamiętaj, że nie określam klauzuli „sortuj według”. Może być lepiej „uporządkować według” czegoś takiego jak klucz podstawowy, który będzie miał indeks - uzyskanie N-tego rekordu z indeksu może być szybsze, jeśli baza danych nie może uzyskać N-tego rekordu z samej bazy danych bez budowania zestawu wyników .
źródło
Najbardziej odpowiednia odpowiedź, jaką widziałem w tym artykule dla serwera SQL
źródło