Zastanawiam się, czy istnieje daleko (prawdopodobnie lepszy sposób) uporządkowania według kolejności wartości w klauzuli IN ().
Problem w tym, że mam 2 zapytania, jedno, które pobiera wszystkie identyfikatory, a drugie, które pobiera wszystkie informacje. Pierwsza tworzy kolejność identyfikatorów, według której chcę, aby druga sortowała. Identyfikatory są umieszczane w klauzuli IN () we właściwej kolejności.
Więc byłoby coś takiego (bardzo uproszczone):
SELECT id FROM table1 WHERE ... ORDER BY display_order, name
SELECT name, description, ... WHERE id IN ([id's from first])
Problem polega na tym, że drugie zapytanie nie zwraca wyników w tej samej kolejności, w jakiej identyfikatory są umieszczane w klauzuli IN ().
Jednym z rozwiązań, które znalazłem, jest umieszczenie wszystkich identyfikatorów w tabeli tymczasowej z polem automatycznie zwiększającym się, które jest następnie łączone z drugim zapytaniem.
Czy jest lepsza opcja?
Uwaga: Ponieważ pierwsze zapytanie jest uruchamiane „przez użytkownika”, a drugie w procesie w tle, nie ma możliwości połączenia zapytania 2 w 1 za pomocą zapytań podrzędnych.
Używam MySQL, ale myślę, że warto byłoby, gdyby zauważył, jakie opcje są dostępne również dla innych baz danych.
źródło
IN
iFIELD
parametry są równe. Wykonanie tego w kodzie programu może być szybsze dzięki wykorzystaniu tej dodatkowej wiedzy. Oczywiście rozsądniej byłoby przełożyć to obciążenie na klienta, a nie na serwer, jeśli myślisz o wydajności serwera.sqlite
?Zobacz, jak uzyskać posortowane dane.
źródło
Dwa rozwiązania, które przychodzą na myśl:
order by case id when 123 then 1 when 456 then 2 else null end asc
order by instr(','||id||',',',123,456,') asc
(
instr()
Jest z Oracle, może maszlocate()
lubcharindex()
czy coś takiego)źródło
Ans, aby uzyskać posortowane dane.
źródło
Jeśli chcesz wykonać dowolne sortowanie zapytania przy użyciu wartości wprowadzonych przez zapytanie w MS SQL Server 2008+ , możesz to zrobić, tworząc w locie tabelę i wykonując takie łączenie (używając nomenklatury z OP).
Jeśli zamienisz instrukcję VALUES na coś innego, co robi to samo, ale w języku ANSI SQL, powinno to działać na każdej bazie danych SQL.
Uwaga: Druga kolumna w utworzonej tabeli (orderTbl.orderIdx) jest niezbędna podczas odpytywania zestawów rekordów większych niż 100 lub więcej. Początkowo nie miałem kolumny orderIdx, ale stwierdziłem, że przy zestawach wyników większych niż 100 musiałem jawnie sortować według tej kolumny; w SQL Server Express 2014 tak czy inaczej.
źródło
orderTbl.orderKey
,orderTbl.orderIndex
przezorderKey
,orderIndex
działał naprawdę świetnie
źródło
Klauzula IN opisuje zbiór wartości, a zbiory nie mają porządku.
Twoje rozwiązanie z łączeniem, a następnie zamawianiem na
display_order
kolumnie jest najbardziej prawie poprawnym rozwiązaniem; cokolwiek innego jest prawdopodobnie hackiem specyficznym dla DBMS (lub robi coś z funkcjami OLAP w standardowym SQL). Z pewnością łączenie jest najbardziej przenośnym rozwiązaniem (chociaż generowanie danych zdisplay_order
wartościami może być problematyczne). Zwróć uwagę, że może być konieczne wybranie kolumn kolejności; kiedyś było to wymaganie w standardowym SQL, chociaż uważam, że z reguły było to nieco złagodzone jakiś czas temu (może tak dawno temu jak SQL-92).źródło
W przypadku Oracle działa rozwiązanie Johna wykorzystujące funkcję instr (). Oto nieco inne rozwiązanie, które zadziałało -
SELECT id FROM table1 WHERE id IN (1, 20, 45, 60) ORDER BY instr('1, 20, 45, 60', id)
źródło
Użyj funkcji MySQL FIND_IN_SET :
źródło
Właśnie próbowałem to zrobić to MS SQL Server gdzie nie mamy FIELD ():
Zwróć uwagę, że zezwalam również na kopiowanie.
źródło
Moją pierwszą myślą było napisanie pojedynczego zapytania, ale powiedziałeś, że nie jest to możliwe, ponieważ jedno jest uruchamiane przez użytkownika, a drugie w tle. Jak przechowujesz listę identyfikatorów, które mają zostać przekazane od użytkownika do procesu w tle? Dlaczego nie umieścić ich w tymczasowej tabeli z kolumną oznaczającą kolejność.
A co powiesz na to:
źródło
Myślę, że powinieneś poradzić sobie z przechowywaniem swoich danych w taki sposób, że po prostu wykonasz połączenie i będzie idealne, więc nie ma hacków i skomplikowanych rzeczy.
Mam na przykład listę identyfikatorów utworów „Ostatnio odtwarzane”, na SQLite po prostu robię:
źródło
Spróbuj tego:
GDZIE prawdopodobnie zajmie trochę czasu, aby skorelowane podzapytania działały poprawnie, ale podstawowa zasada powinna być rozsądna.
źródło