PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Đặt hàng chuỗi varchar dưới dạng số

Hoàn toàn có thể.

ORDER BY varchar_column::int

Đảm bảo có các ký tự số nguyên hợp lệ trong varchar của bạn cho mỗi mục nhập hoặc bạn nhận được một ngoại lệ invalid input syntax for integer: ... . (Khoảng trắng ở đầu và cuối là ok - nó sẽ được cắt tự động.)

Tuy nhiên, nếu đúng như vậy thì tại sao không chuyển đổi cột thành integer đầu tiên là? Nhỏ hơn, nhanh hơn, sạch hơn, đơn giản hơn.

Làm cách nào để tránh các trường hợp ngoại lệ?

Để xóa các ký tự không phải chữ số trước khi truyền và do đó tránh các ngoại lệ có thể xảy ra:

ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
  • regexp_replace() biểu thức loại bỏ hiệu quả tất cả các không phải chữ số, do đó chỉ còn lại các chữ số hoặc một chuỗi trống. (Xem bên dưới.)

  • \D là viết tắt của lớp ký tự [^[:digit:]] , nghĩa là tất cả không phải chữ số ([^0-9] ).
    Trong các phiên bản Postgres cũ với cài đặt lỗi thời standard_conforming_strings = off , bạn phải sử dụng cú pháp chuỗi thoát Posix E'\\D' để thoát khỏi dấu gạch chéo ngược \ . Điều này là mặc định trong Postgres 8.3, vì vậy bạn sẽ cần nó cho phiên bản lỗi thời của mình.

  • Tham số thứ 4 g dành cho "toàn cầu" , hướng dẫn thay thế tất cả lần xuất hiện, không chỉ lần đầu tiên.

  • Bạn có thể muốn cho phép một dấu gạch ngang ở đầu (- ) cho các số âm.

  • Nếu chuỗi không có chữ số nào, kết quả là một chuỗi trống không hợp lệ để truyền thành integer . Chuyển đổi chuỗi trống thành NULL với NULLIF . (Bạn có thể xem xét 0 thay vào đó.)

Kết quả được đảm bảo là hợp lệ. Quy trình này dành cho truyền thành integer như được yêu cầu trong phần nội dung câu hỏi, không dành cho numeric như tiêu đề đã đề cập.

Làm thế nào để làm cho nó nhanh chóng?

Một cách là chỉ mục trên một biểu thức.

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

Sau đó, sử dụng cùng một biểu thức trong ORDER BY mệnh đề:

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

Kiểm tra với EXPLAIN ANALYZE liệu chỉ mục chức năng có thực sự được sử dụng hay không.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cài đặt pg gem; LỖI:Không thể tạo tiện ích mở rộng gốc đá quý

  2. Tự động tạo các cột cho bảng chéo trong PostgreSQL

  3. Trả về giá trị cột trước UPDATE chỉ bằng SQL

  4. Cài đặt trình điều khiển PDO cho PostgreSQL trên Mac (sử dụng Zend cho eclipse)

  5. Sử dụng phép nối để kết hợp dữ liệu từ các bảng khác nhau trong PostgreSQL