SQL 如何返回最大值所在的多條記錄

SQL 中通過 top 或 limit 子句得到第一條數據不難,再配合排序,就能得到最大的那一行:
select top 1 * from T order by f desc

如果最大值有多條記錄,想全部得到,就需要子查詢得到最大值,然後二次遍歷數據得到和最大值相同的所有記錄:
select * from T where f=(select max(f) from T)

或用窗口函數 rank() 做一下排名,然後取第 1 名:
select * from (select T.*,rank()over(partition by 1 order by age desc) f_rank from T) where f_rank=1

無論如何都要分成兩步才能得到結果。試想我們去海邊撿最大的貝殼,一邊走一邊比對就行了,始終保留最大的,同樣大的就都留在手裏,這很自然。但 SQL 表達能力有限,沒有保留多個最大的能力,只能來回走兩趟,這種繞遠的解題思路如果再嵌套幾層,將會給程序員帶來很大的理解負擔。

 

這種情況如果用集算器 SPL 語言就比較容易,從數據庫得到原始數據:

>T=connect(”mysqlDB”).query(“select * from T”)

然後用 maxp 的 @a 選項,就能取出全部的最大值記錄了:

=T.maxp@a(f)

上面這個用法是個小改善,SQL 裏還有更多彆扭、思維方式很繞的計算,根源在於 SQL 依賴的關係代數體系不支持有序集合計算,無法利用數據在集合中的位置,沒有平衡好集合與離散數據的關係。SPL 在做有序集合計算時,對 SQL 裏的 TopN 進行了變種,可以取 TopN 的值 / 記錄 / 記錄在集合中的位置,以應對更廣泛的計算需求;可以應用到分組子集,增強分組後續操作的能力,參考《TopN 及變種》

 

集算器 SPL 是解決 SQL 難題的專業腳本語言,它語法簡單,符合自然思維,是天然分步、層次清晰的面向過程計算語言。它採用與數據庫無關的統一語法,編寫的算法可在數據庫間無縫遷移。它是桌面級計算工具,即裝即用,配置簡單,調試功能完善,可設置斷點、單步執行,每步執行結果都可查看。請參閱SQL 解題手

當數據不在數據庫裏時,SPL 加載數據仍然方便:
=file(“d:/t.csv”).import(;,",")

SPL能很方便地嵌入到JAVA應用,可參考《Java 如何調用 SPL 腳本》

具體使用方法可參考 《如何使用集算器》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章