Ok, mam tabelę z indeksowanym kluczem i nieindeksowanym polem. Muszę znaleźć wszystkie rekordy o określonej wartości i zwrócić wiersz. Chciałbym wiedzieć, czy mogę zamawiać według wielu wartości.
Przykład:
id x_field
-- -----
123 a
124 a
125 a
126 b
127 f
128 b
129 a
130 x
131 x
132 b
133 p
134 p
135 i
pseudo: chciałby, aby wyniki były uporządkowane w ten sposób, where ORDER BY x_field = 'f', 'p', 'i', 'a'
SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'
Wyniki byłyby następujące:
id x_field
-- -----
127 f
133 p
134 p
135 i
123 a
124 a
125 a
129 a
Składnia jest prawidłowa, ale kiedy wykonuję zapytanie, nigdy nie zwraca żadnych wyników, nawet jeśli ograniczę je do 1 rekordu. Czy jest inny sposób, aby to zrobić?
Pomyśl o x_field jako o wynikach testu i muszę zweryfikować wszystkie rekordy, które spełniają warunek. Chciałem uporządkować wyniki testów według wartości nieudanych, wartości przekazanych. Mogłem więc najpierw zweryfikować błędne wartości, a następnie przekazane wartości za pomocą ORDER BY.
Czego nie mogę zrobić:
- GROUP BY, ponieważ muszę zwrócić określone wartości rekordów
- WHERE x_field IN ('f', 'p', 'i', 'a'), potrzebuję wszystkich wartości, ponieważ próbuję użyć jednego zapytania do kilku testów walidacyjnych. A wartości x_field nie są w kolejności DESC / ASC
Po napisaniu tego pytania zaczynam myśleć, że muszę to przemyśleć, LOL!
źródło
Odpowiedzi:
... WHERE x_field IN ('f', 'p', 'i', 'a') ... ORDER BY CASE x_field WHEN 'f' THEN 1 WHEN 'p' THEN 2 WHEN 'i' THEN 3 WHEN 'a' THEN 4 ELSE 5 --needed only is no IN clause above. eg when = 'b' END, id
źródło
Możesz użyć LEFT JOIN z „VALUES ('f', 1), ('p', 2), ('a', 3), ('i', 4)” i użyć drugiej kolumny w zamówieniu -przez wyrażenie. Postgres użyje Hash Join, które będzie znacznie szybsze niż ogromne CASE, jeśli masz dużo wartości. I łatwiej jest automatycznie generować.
Jeśli ta informacja o zamówieniu jest naprawiona, powinna mieć własną tabelę.
źródło
Próbować:
Byłeś na dobrej drodze, ale umieszczając x_field tylko na wartości F, pozostałe 3 były traktowane jako stałe i nie były porównywane z niczym w zbiorze danych.
źródło
Użyj
case
przełącznika, aby przetłumaczyć kody na liczby, które można sortować:ORDER BY case x_field when 'f' then 1 when 'p' then 2 when 'i' then 3 when 'a' then 4 else 5 end
źródło
Znalazłem na to znacznie czystsze rozwiązanie:
Uwaga: pozycja_tablicy wymaga Postgres w wersji 9.5 lub nowszej.
źródło
array_position(ARRAY[1, 0]::integer[], x_field)
Wszystkie sugestie
CASE
iORDER BY
powinny działać, ale mam zamiar zasugerować konia w innym kolorze. Zakładając, że istnieje tylko rozsądna liczba wartościx_field
i już wiesz, jakie one są, utwórz typ wyliczeniowy z F, P, A i I jako wartościami (plus wszelkie inne możliwe wartości). Wyliczenia będą sortowane w kolejności sugerowanej przez ichCREATE
instrukcję. Możesz także używać znaczących nazw wartości - prawdopodobnie tak jest w przypadku Twojej prawdziwej aplikacji i właśnie zamaskowałeś je dla zachowania poufności - bez marnowania miejsca, ponieważ zapisywana jest tylko pozycja porządkowa.źródło
Możesz zamówić według wybranej kolumny lub innych wyrażeń.
Oto przykład, jak uporządkować według wyniku instrukcji case:
SELECT col1 , col2 FROM tbl_Bill WHERE col1 = 0 ORDER BY -- order by case-statement CASE WHEN tbl_Bill.IsGen = 0 THEN 0 WHEN tbl_Bill.IsGen = 1 THEN 1 ELSE 2 END
Wynikiem będzie lista zaczynająca się od wierszy „IsGen = 0”, po których następują wiersze „IsGen = 1”, a wszystkie pozostałe wiersze na końcu.
Na końcu możesz dodać więcej parametrów zamówienia:
SELECT col1 , col2 FROM tbl_Bill WHERE col1 = 0 ORDER BY -- order by case-statement CASE WHEN tbl_Bill.IsGen = 0 THEN 0 WHEN tbl_Bill.IsGen = 1 THEN 1 ELSE 2 END, col1, col2
źródło
Może to być przydatne dla kogoś, kto jest nowy w ORDER BY z CASE
ORDER BY CASE WHEN GRADE = 'A' THEN 0 WHEN GRADE = 'B' THEN 1 ELSE 2 END
źródło
możesz użyć pozycji (tekstu w tekście) w kolejności, aby uporządkować sekwencję
źródło