SQL 如何在時間序列中根據欄位變化分組
將排序(一般按時間排)後的資料按某欄位變化分組統計,也就是分組欄位值與上一行的值比較,如果相同則分到與上一行同組,不同時則建立一個新組。
這個問題用SQL來做很難!
SQL的集合是無序的,早期SQL沒有相鄰行引用的方法。SQL2003標準中加入了視窗函式,能引用相鄰行,但分組仍然非常困難,需要用子查詢人為造出分組序號。
舉個例子:查詢人員某段時間所處城市,並列出起始和結束時間。現有資料庫表footmark資料如下:
NAME | FOOTDATE | CITY |
Tom | 2020-01-02 08:30:00 | Beijing |
Tom | 2020-01-03 08:30:00 | Beijing |
Tom | 2020-01-04 13:30:05 | Beijing |
Tom | 2020-01-04 16:36:00 | Chengdu |
Tom | 2020-01-05 08:30:00 | Chengdu |
Tom | 2020-01-06 12:30:00 | Chengdu |
Tom | 2020-01-06 17:30:25 | Beijing |
Tom | 2020-01-07 09:30:05 | Beijing |
Tom | 2020-01-09 16:30:00 | Beijing |
… | … | … |
要求最終分組統計的結果如下:
NAME | CITY | STARTDATE | ENDDATE |
Tom | Beijing | 2020-01-02 08:30:00 | 2020-01-04 13:30:05 |
Tom | Chengdu | 2020-01-04 16:36:00 | 2020-01-06 12:30:00 |
Tom | Beijing | 2020-01-06 17:30:25 | 2020-01-09 16:30:00 |
以Oracle為例,用SQL寫出來是這樣:
WITH A AS
( SELECT NAME, FOOTDATE, CITY,
CASE WHEN CITY=LAG(CITY) OVER (PARTITION BY NAME ORDER BY FOOTDATE) THEN 0 ELSE ROWNUM END FLAG
FROM FOOTMARK ORDER BY NAME, FOOTDATE),
B AS
( SELECT NAME, FOOTDATE, CITY,
MAX(FLAG) OVER (PARTITION BY NAME ORDER BY FOOTDATE) FLAG
FROM A),
C AS
( SELECT NAME, CITY, FLAG,
MIN(FOOTDATE) STARTDATE,
MAX(FOOTDATE) ENDDATE
FROM B
GROUP BY NAME, CITY, FLAG
ORDER BY NAME, FLAG )
SELECT NAME, CITY, STARTDATE, ENDDATE FROM C;
這裡的FLAG就是人為造出的分組序號,這種SQL既難寫又難懂。
對於這種按順序分組,如果使用集算器的SPL語言就會簡單很多,只需1行程式碼:
connect("mydb").query("SELECT * FROM FOOTMARK ORDER BY NAME,FOOTDATE").groups@o(NAME,CITY;min(FOOTDATE):STARTDATE,max(FOOTDATE):ENDDATE)
SPL基於有序集合實現,提供了按有序分組的選項@o,解決這個問題非常容易。
SPL提供了等值分組、有序分組、有序條件分組、序號分組、巢狀分組、大資料有序分組、大資料有序條件分組等多種分組方式,詳情參考 。
集算器 SPL 是解決 SQL 難題的專業指令碼語言,它語法簡單,符合自然思維,是天然分步、層次清晰的程式導向計算語言。它採用與資料庫無關的統一語法,編寫的演算法可在資料庫間無縫遷移。它是桌面級計算工具,即裝即用,配置簡單,除錯功能完善,可設定斷點、單步執行,每步執行結果都可檢視。請參閱
SPL也能很方便地嵌入到JAVA應用,可參考 。
具體使用方法可參考 。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900830/viewspace-2699084/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- list集合根據某欄位分組
- 根據欄位查表名
- SqlServer根據特定欄位分組後,對需要欄位進行分組拼接SQLServer
- 時間序列結構變化分析:Python實現時間序列變化點檢測Python
- jackson根據屬性名動態序列化物件欄位物件
- sql根據多個欄位查詢重複記錄SQL
- SpringJpa @query 中根據傳入引數(欄位)排序Spring排序
- python-進階教程-根據欄位將記錄分組Python
- js物件陣列(JSON) 根據某個共同欄位 分組物件陣列JSON
- List根據時間排序排序
- js根據時間排序JS排序
- 時間序列的ADF校驗(單位根校驗)
- golang將切片或陣列根據某個欄位進行分組Golang陣列
- jQuery根據表格欄位升序和降序詳解jQuery
- 二維陣列根據欄位進行排序陣列排序
- 二維陣列根據某個欄位排序陣列排序
- js陣列操作——物件陣列根據某個相同的欄位分組JS陣列物件
- SQL-分組聚合 - 單欄位分組SQL
- Go 中時間型別欄位的 JSON 序列化和反序列化的處理技巧Go型別JSON
- Python實用技法第14篇:根據欄位將記錄分組:itertools.groupby()Python
- laravel sync()同步時修改中間表欄位Laravel
- MySQL8 根據某屬性查詢欄位排名由自定義變數到rank()的變動MySql變數
- python 根據時間戳建立目錄操作Python時間戳
- vue+element-ui根據時間查詢VueUI
- Laravel ORM 中,根據關聯查詢的欄位值,對主查詢排名LaravelORM
- php 根據給定字串時間獲取時區PHP字串
- swift4.0 物件資料來源根據屬性分組,時間排序Swift物件排序
- 更新欄位時更新時間不自動更新(不更新 updated_at 欄位)
- Java根據前端返回的欄位名進行查詢資料Java前端
- 根據時間範圍呼叫gitLab介面查詢Gitlab
- MySQL為欄位新增預設時間(插入時間)MySql
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹
- mybatis自動填充時間欄位MyBatis
- BIRT 中如何根據引數動態拼接 SQLSQL
- pandas dataframe 時間欄位 diff 函式函式
- 如何在Excel中根據數量生成抽獎名單Excel
- Java根據前端返回的欄位名進行查詢資料的方法Java前端
- 根據時間經緯度高程計算天頂角