Trudno mi jest przekształcić procedury składowane z SQL Server do Oracle, aby nasz produkt był z nim zgodny.
Mam zapytania, które zwracają najnowszy rekord niektórych tabel na podstawie sygnatury czasowej:
SQL Server:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=> To zwróci mi najnowszy rekord
Ale Oracle:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=> To zwróci mi najstarszy rekord (prawdopodobnie w zależności od indeksu), niezależnie od ORDER BY
instrukcji!
Zapytanie Oracle zawarłem w taki sposób, aby spełniało moje wymagania:
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
i to działa. Ale brzmi to dla mnie jak okropny hack, zwłaszcza jeśli mam dużo rekordów w powiązanych tabelach.
Jaki jest najlepszy sposób, aby to osiągnąć?
sql
oracle
sql-order-by
rownum
Larry
źródło
źródło
Odpowiedzi:
where
Oświadczenie zostanie wykonany przedorder by
. Zatem żądane zapytanie brzmi „ weź pierwszy wiersz, a następnie uporządkuj go wedługt_stamp
opisu ”. A nie tego zamierzasz.Metoda podzapytania jest właściwą metodą w Oracle.
Jeśli chcesz wersję, która działa na obu serwerach, możesz użyć:
Zewnętrzny
*
zwróci „1” w ostatniej kolumnie. Aby tego uniknąć, należałoby wymienić poszczególne kolumny.źródło
Użyj
ROW_NUMBER()
zamiast tego.ROWNUM
jest pseudokolumną iROW_NUMBER()
jest funkcją. Możesz przeczytać o różnicy między nimi i zobaczyć różnicę w wynikach poniższych zapytań:źródło
ROWNUM
może być szybsze niżROW_NUMBER()
to, czy należy użyć jednego nad drugim, zależy od wielu czynników.Alternatywą, którą sugerowałbym w tym przypadku, jest użycie MAX (t_stamp), aby uzyskać najnowszy wiersz ... np
Moje preferencje dotyczące wzorca kodowania (być może) - niezawodne, generalnie działają na poziomie lub lepiej niż próba wybrania pierwszego wiersza z posortowanej listy - również zamiar jest bardziej czytelny.
Mam nadzieję że to pomoże ...
SQLer
źródło
W powyższym komentarzu udokumentowano kilka problemów projektowych z tym związanych. Krótko mówiąc, w Oracle musisz ręcznie ograniczyć wyniki, jeśli masz duże tabele i / lub tabele z takimi samymi nazwami kolumn (i nie chcesz jawnie wpisywać ich wszystkich i zmieniać ich nazw). Prostym rozwiązaniem jest ustalenie punktu przerwania i ograniczenie go w zapytaniu. Możesz też to zrobić w zapytaniu wewnętrznym, jeśli nie masz ograniczenia dotyczącego nazw kolumn powodujących konflikt. Na przykład
znacznie ograniczy wyniki. Następnie możesz ORDER BY lub nawet wykonać zapytanie zewnętrzne, aby ograniczyć liczbę wierszy.
Myślę też, że TOAD ma funkcję ograniczania wierszy; ale nie jestem pewien, czy to ogranicza w ramach rzeczywistego zapytania w Oracle. Niepewny.
źródło