SQL untuk memesan berdasarkan angka - 1,2,3,4 dll, bukan 1,10,11,12

87

Saya mencoba memesan berdasarkan kolom angka di database saya yang memiliki nilai 1-999

Saat saya menggunakan

ORDER_BY registration_no ASC

Saya mendapat….

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

Jadi tampaknya memesan dengan digit pertama berlawanan dengan nomor tersebut.

Adakah yang tahu SQL apa yang digunakan jika saya ingin memesan ini berdasarkan nilai? Jadi 1,2,3,4,5,6dll

Konnor 262
sumber
11
Kolom Anda berjenis varchar yang karenanya Anda menghadapi perilaku ini.
Meherzad
apa datatype dari kolom Registration_no?
Praveen Prasannan
9
Gunakan order by registration_no + 0 ascuntuk memecahkan masalah Anda.
Meherzad
10
Anda tidak boleh menyimpan angka di kolom karakter. Masalah Anda adalah akibat langsung dari kesalahan itu.
a_horse_with_no_name
1
Kolom saya adalah Varchar dan data yang saya simpan adalah Kelas 10 / Kelas 9 / Kelas 8. Sekarang kelas 10 datang sebelum kelas 8. Bagaimana cara mengatasi ini tanpa harus melakukan di kolom display_order?
Vishnoo Rath

Jawaban:

142

Salah satu cara untuk mengurutkan berdasarkan bilangan bulat positif, ketika disimpan sebagai varchar, adalah mengurutkan berdasarkan panjangnya terlebih dahulu, kemudian nilainya:

order by len(registration_no), registration_no

Ini sangat berguna ketika kolom mungkin berisi nilai non-numerik.

Catatan: di beberapa database, fungsi untuk mendapatkan panjang string mungkin dipanggil length()sebagai ganti len().

Gordon Linoff
sumber
1
Ini tidak akan berfungsi di semua kasus. Di luar kepala, kasing yang tidak akan berfungsi adalah campuran bilangan bulat dengan; angka negatif, angka dengan nol di depan, angka dengan pecahan dan kata dan angka digabungkan.
WonderWorker
10
@ Knickerless-Noggings. . . Bacalah kalimat pertama dari jawabannya. Menurut saya cukup jelas.
Gordon Linoff
@GordonLinoff memesan dengan kolom yang sama dua kali tidak intensif cpu dan memori?
loneStar
@Tokopedia . . Jumlah kunci dalam sebuah order byberpengaruh kecil terhadap kinerja.
Gordon Linoff
1
Untuk Oracle SQL, gunakan length()sebagai penggantilen()
Stevoisiak
62
ORDER_BY cast(registration_no as unsigned) ASC

secara eksplisit mengonversi nilai menjadi angka. Kemungkinan lain untuk mencapai hal yang sama adalah

ORDER_BY registration_no + 0 ASC

yang akan memaksa percakapan implisit.

Sebenarnya Anda harus memeriksa definisi tabel dan mengubahnya. Anda dapat mengubah tipe data menjadi intseperti ini

ALTER TABLE your_table MODIFY COLUMN registration_no int;
juergen d
sumber
13

Jika Anda menggunakan SQL Server:

ORDER_BY cast(registration_no as int) ASC
IPOSTEDONCE
sumber
4
ORDER_BY cast(registration_no as unsigned) ASC

memberikan hasil yang diinginkan dengan peringatan.

Oleh karena itu, lebih baik untuk pergi

ORDER_BY registration_no + 0 ASC

untuk hasil yang bersih tanpa peringatan SQL.

priyanka
sumber
Bisakah Anda menjelaskan mengapa melakukan + 0pekerjaan? Saya telah mengujinya pada kumpulan data saya dan memang berhasil, tetapi saya penasaran mengapa? Apakah itu mengubahnya menjadi angka sebelum memesan?
Joshua Pinter
2

Saya berasumsi jenis kolom Anda adalah STRING (CHAR, VARCHAR, dll) dan prosedur penyortiran menyortirnya sebagai string. Yang perlu Anda lakukan adalah mengubah nilai menjadi nilai numerik. Bagaimana melakukannya tergantung pada sistem SQL yang Anda gunakan.


sumber
1

Terkadang Anda tidak punya pilihan untuk menyimpan nomor yang dicampur dengan teks. Di salah satu aplikasi kami, host situs web yang kami gunakan untuk situs e-niaga membuat filter dari daftar secara dinamis. Tidak ada opsi untuk mengurutkan berdasarkan bidang apa pun kecuali teks yang ditampilkan. Saat kami ingin filter dibuat dari daftar yang mengatakan hal-hal seperti 2 "hingga 8" 9 "hingga 12" 13 "hingga 15" dll, kami memerlukannya untuk mengurutkan 2-9-13, bukan 13-2-9 seperti yang akan terjadi saat membaca nilai numerik. Jadi saya menggunakan fungsi Replikasi SQL Server bersama dengan panjang nomor terpanjang untuk mengisi nomor yang lebih pendek dengan spasi di depan. Sekarang 20 diurutkan setelah 3, dan seterusnya.

Saya bekerja dengan tampilan yang memberi saya panjang minimum dan maksimum, lebar, dll. Untuk jenis dan kelas item, dan berikut adalah contoh cara saya membuat teks. (LB n Rendah dan LB n Tinggi adalah ujung Rendah dan Tinggi dari 5 kurung panjang.)

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
Joey Morgan
sumber
1

Saya lebih suka melakukan "PAD" untuk data. MySql menyebutnya LPAD, tetapi Anda dapat melakukan hal yang sama di SQL Server.

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

Rumus ini akan memberikan angka nol di depan berdasarkan panjang Kolom 3. Fungsi ini sangat berguna dalam situasi lain di luar ORDER BY, jadi itulah mengapa saya ingin memberikan opsi ini.

Hasil: 1 menjadi 001, dan 10 menjadi 010, sedangkan 100 tetap sama.

SQLCodingIsFunnn
sumber
0

Masalah ini hanya karena Anda telah mendeklarasikan kolom dalam tipe data CHAR, VARCHAR atau TEXT. Ubah saja datatype ke INT, BIGINT dll. Ini akan menyelesaikan masalah pemesanan kustom Anda.

Dev Rathi
sumber