問題描述
業(yè)務(wù)上碰到個(gè)需求,要求展示的數(shù)據(jù)按照老板給定的部門順序排序,這些部門的順序無法通過原有的字段描述。
解決思路
一開始考慮的解決方法是數(shù)據(jù)庫新增一個(gè)字段,根據(jù)權(quán)重進(jìn)行排序。但是考慮到原有的業(yè)務(wù)邏輯,每個(gè)月每個(gè)部門都有新的數(shù)據(jù)匯總,如果新增字段的話,整個(gè)項(xiàng)目都要大改。
然后考慮過使用一個(gè)數(shù)據(jù)字典存儲(chǔ)權(quán)重,在查詢的時(shí)候做個(gè)多表連接排序,但是因?yàn)椴块T比較多,這個(gè)方法對(duì)性能影響比較大,所以放棄了。
為了在不影響原有功能的情況下實(shí)現(xiàn)這一功能,考慮從sql入手,僅在展示頁面(findAll)時(shí)對(duì)部門進(jìn)行排序,使用order by 關(guān)鍵字。找到一個(gè)mysql函數(shù)——field(str,str1,str2,str3,str4……),感興趣的同學(xué)可以自己看一下,這是個(gè)按照str1,str2,str3,str4……的順序返回str查詢到的結(jié)果集的函數(shù),如果表中str字段值不存在于str1,str2,str3,str4中的記錄,放在結(jié)果集最前面返回。
根據(jù)這個(gè)啟發(fā),選擇了使用find_in_set(str,strList)函數(shù),find_in_set可以返回str在strList中的位置,如果str不在strList中,則返回0,這樣一來,只要將需要排序的sql后加上order by find_in_set(name,list),就可以實(shí)現(xiàn)排序,并且對(duì)整個(gè)項(xiàng)目的其他功能是沒有影響的。后期通過對(duì)list的維護(hù),實(shí)現(xiàn)排序順序的變動(dòng)。
實(shí)踐
建表語句
CREATE TABLE `t_test` (
`id` varchar(40) comment '主鍵id',
`strName` varchar(100) NOT NULL comment '部門名',
`remark` varchar(100) NOT NULL comment '備注',
`cost` int(11) NOT NULL comment '成本',
PRIMARY KEY (`id`) USING BTREE
)
測(cè)試數(shù)據(jù)
insert into `t_test` values(UUID(),'技術(shù)部',null,12);
insert into `t_test` values(UUID(),'銷售部',null,1);
insert into `t_test` values(UUID(),'人資處',null,132);
insert into `t_test` values(UUID(),'辦事處',null,123);
insert into `t_test` values(UUID(),'蘋果部',null,233);
insert into `t_test` values(UUID(),'香蕉部門',null,120);
要求按照:香蕉部門、辦事處、人資處、蘋果部,的順序展示信息,不存在的部門放在最后
解決方案
select * from t_test
order by find_in_set(strName,'香蕉部門,辦事處,人資處,蘋果部');
總結(jié)
這個(gè)方法不一定是最好的,但在綜合考慮開發(fā)成本、對(duì)項(xiàng)目的影響、功能的使用頻率來說,是比較適用于該場(chǎng)景的方案。