SQL 如何查詢每個分組都出現的欄位值

xiaohuihui發表於2020-06-18

資料分組以後,要找出在每個分組中都出現的某個欄位值。

用SQL來解決這個問題並不容易!

SQL缺少單純的分組操作,只能返回各分組的統計值,而不能對各組的成員再進行更細的交、差、並等集合運算。要解決這種問題就需要多層巢狀子查詢來變相地實現。

舉個例子:查詢每週都加班的員工以進行表彰。現有加班資料表OVERTIME_WORK資料如下:

WORKDATE NAME
2019-07-01 Tom
2019-07-02 John
2019-07-03 Tom
2019-07-04 Cart
2019-07-08 Tom
2019-07-09 Jordan
2019-07-10 Kate
2019-07-10 John
2019-07-15 Leon
2019-07-16 John
2019-07-17 Tom
2019-07-18 John
2019-07-22 Jim
2019-07-23 Tom
2019-07-24 John
2019-07-25 Cart

 

以Oracle為例,用SQL寫出來是這樣:

WITH A AS

       (SELECT COUNT(*) NUM FROM

        (SELECT DISTINCT TO_CHAR(WORKDATE,'IW') FROM OVERTIME_WORK )

        ),

B AS

        (SELECT TO_CHAR(WORKDATE,'IW') W, NAME

        FROM OVERTIME_WORK

        GROUP BY TO_CHAR(WORKDATE,'IW'), NAME

        ),

C AS

       (SELECT NAME, COUNT(*) NUM FROM B GROUP BY NAME )

SELECT NAME FROM C WHERE NUM=(SELECT NUM FROM A);

這裡的A查出共有幾周,B查出每週加班的不同員工,C查出B裡各員工的出現次數,最後從C裡選出出現次數與總週數相等的員工。解決思路比較繞,這種SQL既難寫又難懂。

 

集算器的SPL語言支援集合運算,解決這個問題就會簡單很多,計算出每週加班員工的交集即可,只需1行程式碼:

connect("mydb").query("SELECT * FROM OVERTIME_WORK").group((WORKDATE-date("2019-07-01"))\7).(~.(NAME)).isect()

【問題延伸】

* 查詢每週至少加班兩次的員工

* 查詢每個月消費金額均排在前20名的客戶名稱

 

SPL 擅長解決這類分組子集和組內有序計算,請閱 、 、 、

集算器 SPL 是解決 SQL 難題的專業指令碼語言,它語法簡單,符合自然思維,是天然分步、層次清晰的程式導向計算語言。它採用與資料庫無關的統一語法,編寫的演算法可在資料庫間無縫遷移。它是桌面級計算工具,即裝即用,配置簡單,除錯功能完善,可設定斷點、單步執行,每步執行結果都可檢視。請參閱

SPL也能很方便地嵌入到JAVA應用,可參考 。

具體使用方法可參考 。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900830/viewspace-2699098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章