SQL để sắp xếp theo số - 1,2,3,4, v.v. thay vì 1,10,11,12


86

Tôi đang cố gắng sắp xếp theo một cột số trong cơ sở dữ liệu của mình có giá trị 1-999

Khi tôi sử dụng

ORDER_BY registration_no ASC

Tôi có….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

Vì vậy, nó dường như được sắp xếp theo chữ số đầu tiên trái ngược với số.

Có ai biết những gì SQL để sử dụng nếu tôi muốn đặt hàng này theo giá trị? Vì vậy, 1,2,3,4,5,6vv


11
Cột của bạn thuộc loại varchar vì bạn đang đối mặt với hành vi này.
Meherzad

kiểu dữ liệu của cột register_no là gì?
Praveen Prasannan

9
Sử dụng order by registration_no + 0 ascđể giải quyết vấn đề của bạn.
Meherzad

10
Bạn không bao giờ nên lưu trữ số trong một cột ký tự. Vấn đề của bạn là kết quả trực tiếp của lỗi đó.
a_horse_with_no_name

Cột của tôi là Varchar và dữ liệu tôi lưu trữ là Lớp 10 / Lớp 9 / Lớp 8. Bây giờ lớp 10 đến trước lớp 8. Làm cách nào để giải quyết vấn đề này mà không cần phải thực hiện cho cột display_order?
Vishnoo Rath

Câu trả lời:


139

Một cách để sắp xếp theo số nguyên dương, khi chúng được lưu trữ dưới dạng varchar, là sắp xếp theo độ dài trước rồi mới đến giá trị:

order by len(registration_no), registration_no

Điều này đặc biệt hữu ích khi cột có thể chứa các giá trị không phải số.

Lưu ý: trong một số cơ sở dữ liệu, hàm lấy độ dài của chuỗi có thể được gọi length()thay vì len().


1
Điều này sẽ không hoạt động trong mọi trường hợp. Ngoài ra, các trường hợp sẽ không hoạt động là hỗn hợp các số nguyên với; số âm, số có số 0 ở đầu, số có phân số và từ và số kết hợp.
WonderWorker

10
@ Knickerless-Noggins. . . Đọc câu đầu tiên của câu trả lời. Tôi nghĩ rằng nó là khá rõ ràng.
Gordon Linoff

@GordonLinoff sắp xếp theo cùng một cột hai lần không phải là cpu và bộ nhớ nhiều?
aloneStar

@Achyuth. . . Số lượng phím trong một order byít ảnh hưởng đến hiệu suất.
Gordon Linoff

1
Đối với Oracle SQL, hãy sử dụng length()thay vìlen()
Stevoisiak Ngày

61
ORDER_BY cast(registration_no as unsigned) ASC

chuyển đổi rõ ràng giá trị thành một số. Một khả năng khác để đạt được điều tương tự sẽ là

ORDER_BY registration_no + 0 ASC

điều này sẽ tạo ra một cuộc trò chuyện ngầm.

Trên thực tế, bạn nên kiểm tra định nghĩa bảng và thay đổi nó. Bạn có thể thay đổi kiểu dữ liệu thành intnhư thế này

ALTER TABLE your_table MODIFY COLUMN registration_no int;

13

Nếu bạn đang sử dụng SQL Server:

ORDER_BY cast(registration_no as int) ASC

3
ORDER_BY cast(registration_no as unsigned) ASC

đưa ra kết quả mong muốn với các cảnh báo.

Do đó, tốt hơn là đi cho

ORDER_BY registration_no + 0 ASC

để có kết quả rõ ràng mà không có bất kỳ cảnh báo SQL nào.


2

Tôi giả sử loại cột của bạn là STRING (CHAR, VARCHAR, v.v.) và quy trình sắp xếp đang sắp xếp nó dưới dạng chuỗi. Việc bạn cần làm là chuyển giá trị thành giá trị số. Cách thực hiện sẽ phụ thuộc vào hệ thống SQL mà bạn sử dụng.


1

Đôi khi bạn không có lựa chọn nào khác về việc phải lưu trữ các số trộn lẫn với văn bản. Trong một trong các ứng dụng của chúng tôi, máy chủ lưu trữ trang web mà chúng tôi sử dụng cho trang thương mại điện tử của mình tạo bộ lọc động ra khỏi danh sách. Không có tùy chọn để sắp xếp theo bất kỳ trường nào ngoài văn bản được hiển thị. Khi chúng tôi muốn các bộ lọc được xây dựng dựa trên danh sách cho biết những thứ như 2 "đến 8" 9 "đến 12" 13 "đến 15", v.v., chúng tôi cần nó sắp xếp 2-9-13, không phải 13-2-9 như khi đọc các giá trị số. Vì vậy, tôi đã sử dụng hàm SQL Server Replicate cùng với độ dài của số dài nhất để đệm bất kỳ số nào ngắn hơn bằng khoảng trắng ở đầu. Bây giờ 20 được sắp xếp sau 3, v.v.

Tôi đang làm việc với một dạng xem cung cấp cho tôi chiều dài, chiều rộng, v.v. tối thiểu và tối đa cho loại mục và lớp và đây là một ví dụ về cách tôi thực hiện văn bản. (LB n Thấp và LB n Cao là giá trị cuối Thấp và Cao của 5 dấu ngoặc nhọn.)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text

1

Tôi thích thực hiện một "PAD" cho dữ liệu. MySql gọi nó là LPAD, nhưng bạn có thể làm theo cách của mình để làm điều tương tự trong SQL Server.

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

Công thức này sẽ cung cấp các số 0 đứng đầu dựa trên độ dài của Cột là 3. Chức năng này rất hữu ích trong các tình huống khác ngoài ORDER BY, vì vậy đó là lý do tại sao tôi muốn cung cấp tùy chọn này.

Kết quả: 1 trở thành 001 và 10 trở thành 010, trong khi 100 vẫn giữ nguyên.


0

Sự cố này chỉ là do bạn đã khai báo cột trong kiểu dữ liệu CHAR, VARCHAR hoặc TEXT. Chỉ cần thay đổi kiểu dữ liệu thành INT, BIGINT, v.v. Điều này sẽ giải quyết được vấn đề đặt hàng tùy chỉnh của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.