2012-08-23 12 views
11

Tôi có chuỗi như M1 M3 M4 M14 M30 M40 vv (thực sự bất kỳ int 2-3 chữ số sau một bức thư) Khi tôi làm "ORDER BY tên" này trả về:MySQL trật tự của chuỗi với số

M1, M14, M3, M30, M4, M40

Khi tôi muốn:

M1, M3, M4, M14, M30, M40 của nó đối xử với toàn bộ điều như là một chuỗi nhưng tôi muốn đối xử với nó như chuỗi + int

Bất kỳ ý tưởng?

+0

http://stackoverflow.com/a/153642/1013082 – MetalFrog

+0

Sẽ có lúc nào cũng chỉ là một lá thư vào đầu của chuỗi? –

+0

http://stackoverflow.com/a/12257917/2008111 – caramba

Trả lời

10

Bạn có thể sử dụng SUBSTR và CAST AS UNSIGNED/KÝ trong ORDER BY:

SELECT * FROM table_name ORDER BY 
    SUBSTR(col_name FROM 1 FOR 1), 
    CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) 
+0

hoạt động rất tốt! Chỉ cần thay đổi từ 1 FOR 2 thành FROM 1 FOR 1 và làm việc –

+0

câu trả lời tuyệt vời ... bạn đã làm cho ngày của tôi! cảm ơn! – Monica

+1

@rocky phải làm gì nếu không có định dạng cố định, có thể chuỗi thích: test1,1test, te2st, test11,2131,10t, t22g –

1

Bạn có thể sử dụng:

order by name,SUBSTRING(name,1,LENGTH(name)-1) 
+0

Đối với tôi, đây là giải pháp phù hợp. Cảm ơn! – Stimart

3

Nếu có thể có nhiều nhân vật ở phần đầu của chuỗi, cho ví dụ như 'M10', 'MTR10', 'ABCD50', 'JL8', etc..., về cơ bản bạn phải lấy chuỗi con của tên từ vị trí đầu tiên của một số.

Thật không may MySQL không hỗ trợ loại hoạt động REGEXP đó (chỉ một giá trị boolean được trả về, không phải là kết quả thực tế).

Bạn có thể sử dụng giải pháp này để bắt chước nó:

SELECT name 
FROM  tbl 
ORDER BY CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN 
        CAST(name AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,1) 
       WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,2) 
       WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,3) 
       WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,4) 
       WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,5) 
       WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,6) 
       WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,7) 
     END, 
     CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,1) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,2) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,3) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,4) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,5) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,6) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,7) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,8) AS UNSIGNED) 
     END 

này sẽ đặt bởi phần nhân vật của chuỗi đầu tiên, sau đó số trích một phần của chuỗi càng lâu càng có < = 7 ký tự tại sự bắt đầu của chuỗi. Nếu bạn cần nhiều hơn, bạn chỉ có thể thêm WHEN s vào câu hỏi CASE.

+0

đã làm việc cho tôi. Cảm ơn :) –

+0

đã hoạt động nhưng cách đặt hàng nếu giá trị số của nó như: 'M10', '40', 'MTR10', 'ABCD50', '8', 'JL8', '55' – sytolk

+0

Cần thêm ORDER Theo tên * 1, CASE .. trước khi CASE đầu tiên hoạt động nếu nó có số sạch giữa chuỗi hỗn hợp có số. – sytolk

0

Nó chia số và chữ cái riêng biệt.

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(col,'1', 1), '2', 1), '3', 1), '4', 1), '5', 1), '6', 1) 
, '7', 1), '8', 1), '9', 1), '0', 1) as new_col 
FROM table group by new_col; 
1

tôi không thể có được điều này làm việc cho vấn đề của tôi được sắp xếp MLS số như dưới đây:

V12345 V1000000 V92832

Vấn đề được V1000000 đã không được đánh giá cao hơn nghỉ ngơi mặc dù nó lớn hơn.

Sử dụng này giải quyết vấn đề của tôi:

ORDER BY CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) DESC 

Chỉ cần loại bỏ các SUBSTR(col_name FROM 1 FOR 1)

0

Hãy thử loại bỏ các nhân vật với SUBSTR. Sau đó sử dụng ABS để có được những giá trị tuyệt đối từ lĩnh vực:

SELECT * FROM table ORDER BY ABS(SUBSTR(field,1));