簡體   English   中英

SQL 命令字符串作為數字

[英]SQL order string as number

我將數字作為VARCHAR保存到 MySQL 數據庫中。 由於某些其他取決於情況,我無法將它們設為INT

排序時將它們作為字符而不是數字。

在數據庫中我有

1 2 3 4 5 6 7 8 9 10...

在我的頁面上,它顯示了這樣的有序列表:

1 10 2 3 4 5 6 7 8 9

我怎樣才能讓它看起來按數字升序排列?

如果可能的話,如果您只存儲數字,則應該將列的數據類型更改為數字。

如果你不能這樣做,那么將你的列值顯式地轉換為一個integer

select col from yourtable
order by cast(col as unsigned)

或者隱式地使用強制轉換為數字的數學運算

select col from yourtable
order by col + 0

順便說一句,MySQL 從左到右轉換字符串。 例子:

string value  |  integer value after conversion
--------------+--------------------------------
'1'           |  1
'ABC'         |  0   /* the string does not contain a number, so the result is 0 */
'123miles'    |  123 
'$123'        |  0   /* the left side of the string does not start with a number */

另一種方式,不使用單個演員表。

(對於使用 JPA 2.0 的人,不允許轉換)

select col from yourtable
order by length(col),col

編輯:僅適用於正整數

另一種簡單的方法

ORDER BY ABS(column_name)

我排序的列有字母和數字的任意組合,所以我使用這篇文章中的建議作為起點並想出了這個。

DECLARE @tmp TABLE (ID VARCHAR(50));
INSERT INTO @tmp VALUES ('XYZ300');
INSERT INTO @tmp VALUES ('XYZ1002');
INSERT INTO @tmp VALUES ('106');
INSERT INTO @tmp VALUES ('206');
INSERT INTO @tmp VALUES ('1002');
INSERT INTO @tmp VALUES ('J206');
INSERT INTO @tmp VALUES ('J1002');

SELECT ID, (CASE WHEN ISNUMERIC(ID) = 1 THEN 0 ELSE 1 END) IsNum
FROM @tmp
ORDER BY IsNum, LEN(ID), ID;

結果

ID
------------------------
106
206
1002
J206
J1002
XYZ300
XYZ1002

希望這可以幫助

它可能會幫助正在尋找相同解決方案的人。

select * from tablename ORDER BY ABS(column_name)

這對我有用。

select * from tablename
order by cast(columnname as int) asc

另一種轉換方式。

如果您有字符串字段,您可以按以下方式轉換它或其數字部分:添加前導零以使所有整數字符串具有相同的長度。

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( stringfield ) ) , stringfield ) 

或按字段的一部分排序,例如“tensymbols13”、“tensymbols1222”等。

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( LEFT( stringfield , 10 ) ) ) , LEFT( stringfield , 10 ) ) 

這將處理負數、分數、字符串等所有內容:

ORDER BY ISNUMERIC(col) DESC, Try_Parse(col AS decimal(10,2)), col;

我也在尋找具有字母前綴的排序字段。 這是我找到的解決方案。 這可能有助於尋找相同解決方案的人。

字段值:

FL01,FL02,FL03,FL04,FL05,...FL100,...FL123456789

select SUBSTRING(field,3,9) as field from table order by SUBSTRING(field,3,10)*1 desc

SUBSTRING(field,3,9)我輸入 9 因為 9 足以讓我保存最多 9 位整數值。

所以結果將是 123456789 123456788 123456787... 100 99... 2 1

如果您使用的是 AdonisJS 並且具有混合 ID,例如 ABC-202、ABC-201...,您可以將原始查詢與查詢生成器結合起來並實施上述解決方案 ( https://stackoverflow.com/a/25061144/4040835 )如下:

const sortField =
  'membership_id'
const sortDirection =
  'asc'
const subquery = UserProfile.query()
  .select(
    'user_profiles.id',
    'user_profiles.user_id',
    'user_profiles.membership_id',
    'user_profiles.first_name',
    'user_profiles.middle_name',
    'user_profiles.last_name',
    'user_profiles.mobile_number',
    'countries.citizenship',
    'states.name as state_of_origin',
    'user_profiles.gender',
    'user_profiles.created_at',
    'user_profiles.updated_at'
  )
  .leftJoin(
    'users',
    'user_profiles.user_id',
    'users.id'
  )
  .leftJoin(
    'countries',
    'user_profiles.nationality',
    'countries.id'
  )
  .leftJoin(
    'states',
    'user_profiles.state_of_origin',
    'states.id'
  )
  .orderByRaw(
    `SUBSTRING(:sortField:,3,15)*1 ${sortDirection}`,
    {
      sortField: sortField,
    }
  )
  .paginate(
    page,
    per_page
  )

注意:在這一行中: SUBSTRING(:sortField:,3,15)*1 ${sortDirection}

  1. '3'代表數字前最后一個非數字字符的索引號。 如果您的混合 ID 是“ABC-123”,則您的索引號將為 4。
  2. '15'用於在連字符后捕獲盡可能多的數字。
  3. '1'對子字符串執行數學運算,有效地將子字符串轉換為數字。

參考 1:您可以在此處閱讀有關原始查詢中參數綁定的更多信息: https ://knexjs.org/#Raw-Bindings 參考 2:Adonis 原始查詢: https ://adonisjs.com/docs/4.1/query-builder# _raw_queries

將您的字段更改為 INT 而不是 VARCHAR。

由於某些其他取決於情況,我無法將它們設為 INT。

然后先修復依賴的環境。 否則,您正在解決真正的潛在問題。 使用 MySQL CAST 是一種選擇,但它掩蓋了應該修復的錯誤模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM