PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zamów ciąg varchar jako numeryczny

To absolutnie możliwe.

ORDER BY varchar_column::int

Upewnij się, że w swoim varchar masz prawidłowe literały liczb całkowitych kolumna dla każdego wpisu lub otrzymasz wyjątek invalid input syntax for integer: ... . (Pierwsze i końcowe białe znaki są w porządku – zostaną przycięte automatycznie.)

Jeśli tak jest, to dlaczego nie przekonwertować kolumny na integer? najpierw? Mniejszy, szybszy, czystszy, prostszy.

Jak unikać wyjątków?

Aby usunąć znaki niecyfrowe przed rzutowaniem i tym samym uniknąć możliwych wyjątków:

ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
  • regexp_replace() wyrażenie skutecznie usuwa wszystkie cyfry niebędące cyframi, więc pozostają tylko cyfry lub pusty ciąg. (Patrz poniżej.)

  • \D jest skrótem klasy znaków [^[:digit:]] , co oznacza wszystkie cyfry niebędące cyframi ([^0-9] ).
    W starych wersjach Postgresa z przestarzałym ustawieniem standard_conforming_strings = off , musisz użyć składni łańcucha ucieczki Posix E'\\D' aby zmienić ukośnik odwrotny \ . To było domyślne w Postgres 8.3, więc będziesz potrzebować tego w swojej przestarzałej wersji.

  • Czwarty parametr g jest dla „globalnie” , instruując zastąpienie wszystkich wystąpienia, nie tylko pierwsze.

  • możesz chcesz zezwolić na wiodący myślnik (- ) dla liczb ujemnych.

  • Jeśli ciąg w ogóle nie zawiera cyfr, wynikiem jest pusty ciąg, który nie jest prawidłowy do rzutowania na integer . Konwertuj puste ciągi na NULL z NULLIF . (Możesz rozważyć 0 zamiast tego.)

Wynik jest gwarantowany. Ta procedura dotyczy rzutowania na integer zgodnie z żądaniem w treści pytania, nie dla numeric jak wskazuje tytuł.

Jak zrobić to szybko?

Jednym ze sposobów jest indeks wyrażenia.

CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));

Następnie użyj tego samego wyrażenia w ORDER BY klauzula:

ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)

Przetestuj za pomocą EXPLAIN ANALYZE czy indeks funkcjonalny faktycznie jest używany.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja lower() na znakach międzynarodowych w postgresql

  2. Jak zwrócić tablicę jsonb i tablicę obiektów z moich danych?

  3. USUŃ KASKADOWE tylko raz

  4. Czy zapytania typu SELECT są jedynym typem, który można zagnieżdżać?

  5. BŁĄD:nie ma unikalnego ograniczenia pasującego do podanych kluczy dla paska tabeli, do którego się odwołuje