2010-01-12 6 views
7

Chỉ cần đặt một câu hỏi khá giống với câu hỏi này ...MySQL Orderby a number, Empty Strings (hoặc 0's) Cuối cùng

Hiện tại tôi đang làm một OrderBy rất cơ bản trong tuyên bố của mình.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC 

Vấn đề với điều này là các mục chuỗi rỗng cho 'vị trí' được coi là 0. Vì vậy, tất cả các mục có vị trí là chuỗi rỗng xuất hiện trước những người có 1,2,3,4. ví dụ:

'', '', '', 1, 2, 3, 4

hoặc

0, 0, 0, 1, 2, 3, 4

Có một cách để đạt được thứ tự sau:

1, 2, 3, 4, '', '', ''.

hoặc

1, 2, 3, 4, 0, 0, 0.

Tôi giả sử các giải pháp có thể có một số loại thay thế chức năng nhưng tôi đã không thể tìm thấy một chức năng mà làm những gì tôi sau, thông qua google.

Nhiều Cảm ơn,

JonB

Trả lời

15
SELECT * 
FROM tablename 
WHERE visible=1 
ORDER BY 
    case when position in('', '0') then 1 else 0 end, 
    position ASC, 
    id DESC 
+1

Tôi nghĩ điều này sẽ hiệu quả nhưng đó không phải là giải pháp tốt nhất. Tôi nghĩ rằng 'vị trí' phải là một cột số nguyên, và nếu trường hợp đó xảy ra, biểu thức' CASE' cũng nên sử dụng các số nguyên chứ không phải các chuỗi. Nếu 'vị trí' không phải là số nguyên hoặc ít nhất là số, sắp xếp làm số sẽ không hoạt động. Ngoài ra, các giải pháp này thêm một cột mới để sắp xếp, có khả năng sẽ có tác động tiêu cực đến hiệu suất.Nếu giả định rằng 'vị trí' thực sự là một số nguyên là chính xác, thì OP có thể có nghĩa là giá trị' NULL', nơi anh ta viết 'chuỗi rỗng', nghĩa là bạn có thể chỉ cần viết 'ORDER BY COALESCE (vị trí, ~ 0), id DESC' –

+0

@Roland: OP ngụ ý khá rõ ràng rằng vị trí là một chuỗi: * "Vấn đề với điều này là các mục chuỗi rỗng cho 'vị trí' được coi là 0." * – RedFilter

+0

OrbMan có, anh ấy đã làm. Và tôi đang nói rằng đó có lẽ là một phần của vấn đề. Đề xuất của tôi là cung cấp cho nó một loại dữ liệu thích hợp lên phía trước thay vì cố gắng để lau lên sau đó. –

0

bạn có thể cố gắng tham gia hai truy vấn phụ nơi người ta chọn id> 0 và không có sản phẩm nào và người kia chọn sản phẩm nào và 0 chỉ

1

Bạn có thể thử a CASE statement, như sau:

SELECT * 
FROM tablename 
WHERE visible = 1 
ORDER BY CASE position WHEN '' THEN '9999' ELSE position END CASE ASC, 
    ID DESC 
+0

Tôi nhận ra đây là một câu trả lời cũ, nhưng nó chỉ lưu mông của tôi. Cảm ơn, người đàn ông! – mingos

1

Bạn nói rằng position chứa các mục chuỗi rỗng ... Bạn có thực sự có nghĩa là chuỗi rỗng, hoặc bạn có nghĩa là NULL? Nếu nó thực sự chứa NULL mục, bạn nên sử dụng một sửa đổi nhỏ của tuyên bố Orbman của:

SELECT * 
FROM tablename 
WHERE visible=1 
ORDER BY 
    COALESCE(position, ~0) 
, id DESC 

COALESCE() trả về giá trị của đối số đầu tiên đó là NOT NULL. ~ 0 là một phần ma thuật đen sẽ giúp bạn có được giá trị số nguyên tối đa được hỗ trợ bởi MySQL. (~ làm một sự phủ định bitwise, biến tất cả 0 bit thành 1). Vì vậy, trong trường hợp này, nếu position IS NULL là true, nó sẽ trả về 18446744073709551615, nếu không nó sẽ trả về giá trị position.

Tôi cũng muốn chỉ ra rằng loại dữ liệu của cột position rất có thể là một số loại số nguyên (xem http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html). Vì bạn đề cập đến các chuỗi rỗng, tôi nghĩ bạn nên kiểm tra định nghĩa bảng của mình bằng cách thực hiện SHOW CREATE TABLE <tablename>. Nếu vị trí không phải là loại số nguyên, tôi khuyên bạn nên thay đổi vị trí đó. Lý do chính là các chuỗi, ngay cả khi chúng trông giống như các con số, không phân loại như số.