代碼的海,就像我們人生一樣。努力朝着一個方向前進,總比盲目的隨波逐流更能快速有效的到達彼岸。
今天在項目上遇到這樣一個問題:當數據源爲SQLServer,加上一個不成熟的分頁插件時,“union all”與“order by”的親密接觸就會遇到諸多問題。
開發環境如下:
語言:JAVA
框架:spring boot,MyBatis
數據庫:SQLServer
一、先來說一下關於SQLServer關鍵詞,“union all”與“order by”的問題:
先來看下一下語句是否存在問題:
select *
from (
select * from abc1
union all
select * from abc2
) t
order by t.xxx
這樣的語句,在SQLServer中執行,並不會有什麼問題。但是如果以上面的SQL語句爲子查詢,在外面再包裹一層SQL用作業務處理的話,那麼恭喜你,SQLServer會毫不留情的提示你:
除非另外還指定了 TOP 或 FOR XML,否則,ORDER BY 子句在視圖、內聯函數、派生表、子查詢和公用表表達式中無效。
這時候,只需要在select 後面加上“top 100 PERCENT”,然後在外面包裹一層就可以正常執行了。具體原因可自行百度。
二、再來說一下,按照上面的問題處理好SQL語句後,如果需要分頁的話,那麼可能問題又來了:
1、先來看下未加分頁正確的SQL語句:
SELECT top 100 percent *
from (
select * from abc1
union all
select * from abc2
) t
order by t.CLINICAL_DATE DESC
如果這時候你所用到的分頁插件不怎麼成熟,那麼代碼就會變成這樣:
WITH query AS (
SELECT TOP 100 PERCENT ROW_NUMBER() OVER (order by xxx) as __row_number__, top 100 percent *
from (
select * from abc1
union all
select * from abc2
) t
order by xxx
) SELECT * FROM query WHERE __row_number__ BETWEEN 1 AND 15 ORDER BY __row_number__
執行的時候,會提示你“top”附近有語法錯誤,原因是分頁插件只判斷了在SELECT語句後追加分頁屬性,而沒有判斷有top的這種情況。
2、解決辦法:
(1)、自用分頁插件時,升級分頁插件,加上更多、更復雜條件的判斷(推薦這種方案,因爲以後肯定有更多地方用到);
(2)、手動編寫分頁代碼;
(3)、避免在不瞭解所使用的分頁插件時,並需要排序的情況下使用“union all”關鍵詞。
如果大家有更好的方案,歡迎留言交談,互相切磋。