iT邦幫忙

0

SQL排序問題(先null->英文->數字)想請教優化方式

  • 分享至 

  • xImage

想請教各位關於排序上可以優化的方式,目前有一個table如下圖
https://ithelp.ithome.com.tw/upload/images/20221009/201271596ytRPVDdQw.png
想要排序的順序為 先null->英文(只要英文就是要先排序)->數字
最終的結果應該如下圖
https://ithelp.ithome.com.tw/upload/images/20221009/20127159ctubDkOGxe.png
目前自己下的語法如下(用Teradata資料庫)

sel test,
CASE WHEN trim(nvl(test,''))='' THEN 0
WHEN substr(test,1,1) BETWEEN 'A' AND 'Z' THEN 1 ELSE 2 END T1,
CASE WHEN substr(test,2,1) BETWEEN 'A' AND 'Z' THEN 0 ELSE 1 END T2,
CASE WHEN substr(test,3,1) BETWEEN 'A' AND 'Z' THEN 0 ELSE 1 END T3,
CASE WHEN substr(test,4,1) BETWEEN 'A' AND 'Z' THEN 0 ELSE 1 END T4
FROM PSTAGE_DVM.TEST
ORDER BY T1||substr(test,1,1)||T2||substr(test,2,1)||T3||substr(test,3,1)||T4||substr(test,4,1)

但是知道這樣會很影響效能,目前還在思考可以優化的方式
故想請教各位如果是這種特殊排序是否有更好的優化方式 謝謝!

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
石頭
iT邦高手 1 級 ‧ 2022-10-10 00:23:21

可以用空間換時間

建立一個欄位代表 Priority 在新增 & 更新資料異動此 Priority

--null->英文->數字

null = 0
英文 = 1
數字 = 2

上面建立一個 Index 效能理論會提升

2
一級屠豬士
iT邦大師 1 級 ‧ 2022-10-10 01:50:54

使用PostgreSQL

CREATE COLLATION ithelp1010_weird (
   PROVIDER = 'icu',
   LOCALE = 'en-u-kr-space-latn-digit'
);

create table it221010 (
  id int primary key
, test text
);

insert into it221010 values
(1, 'AB'),(2, '12'), (3, 'BX'), (4, NULL), (5, '34'), (6, '');


select *
  from it221010
 order by test COLLATE ithelp1010_weird nulls first;

id 	test
4 	null
6 	
1 	AB
3 	BX
2 	12
5 	34

Demo

0
OuJiaHao
iT邦新手 4 級 ‧ 2022-10-10 03:57:00

以下是用 MSSQL 的做法
也提供給你參考看看

drop table if exists TestData

create table TestData(
    test nvarchar(100)
);

insert into TestData
values (null), ('A0'), ('B0'), ('234'), ('BA'), ('AB'), ('B345'), ('12'), ('9999'), ('24')
GO

select [test] 
from TestData
order by IIF(test like '[a-zA-Z]%' or test is null, 0, 1)
mecerwu iT邦新手 5 級 ‧ 2022-10-24 10:00:04 檢舉

根據樓主的需求(先null->英文->數字),小小改寫了 OuJiaHao 大大的條件式為:
order by CAST( IIF(test like '[a-zA-Z]%' or test is null, 0, 1) AS nvarchar ) + test

OuJiaHao iT邦新手 4 級 ‧ 2022-10-24 15:01:17 檢舉

感謝 mecerwu 大大提醒,沒發現數值部分沒有排序到XDD
如果是這樣的話在條件式改成以下即可達成

select [test] 
from TestData
order by CAST( IIF(test like '[a-zA-Z]%' or test is null, 0, test) AS nvarchar ) 
2
japhenchen
iT邦超人 1 級 ‧ 2022-10-11 08:18:17

我比較直,不改動資料庫,只用ORDER BY CASE .... WHEN ... END 一行搞定

用公司的800多現職員工來做例子

SELECT * FROM EMPLOYEE 
WHERE QUITDATE IS NULL
ORDER BY CASE LEFT(EMPCNAME,1) WHEN '許' THEN 0 WHEN '吳' THEN 1 ELSE 3 END

https://ithelp.ithome.com.tw/upload/images/20221011/201179544nLVdZ8LuB.png
你的問題比照辦理,做成視圖view即可

我要發表回答

立即登入回答