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
- 根據欄位查表名
- SQL Server中根據某個欄位,ID欄位自動增長的實現SQLServer
- 根據時間欄位匯入資料的問題總結
- 時間序列結構變化分析:Python實現時間序列變化點檢測Python
- sql根據多個欄位查詢重複記錄SQL
- [PY3]——根據某個特定的欄位來分組迭代訪問一個欄位或序列?/ itertools.groupby( )函式函式
- jackson根據屬性名動態序列化物件欄位物件
- Gridview繫結資料庫的欄位,根據條件欄位顏色改變View資料庫
- 根據欄位名查詢所有表
- js物件陣列(JSON) 根據某個共同欄位 分組物件陣列JSON
- python-進階教程-根據欄位將記錄分組Python
- js根據時間排序JS排序
- List根據時間排序排序
- SpringJpa @query 中根據傳入引數(欄位)排序Spring排序
- golang將切片或陣列根據某個欄位進行分組Golang陣列
- 根據上一行填充本行的空白欄位,SQL處理方式SQL
- js陣列操作——物件陣列根據某個相同的欄位分組JS陣列物件
- 二維陣列根據欄位進行排序陣列排序
- 二維陣列根據某個欄位排序陣列排序
- jQuery根據表格欄位升序和降序詳解jQuery
- SQL根據分組求連續範圍SQL
- js記一個根據欄位排序物件函式JS排序物件函式
- 根據不同欄位,升降序排列查詢結果
- PHP二維陣列根據某個欄位排序PHP陣列排序
- laravel sync()同步時修改中間表欄位Laravel
- T-sql 根據日期時間 按年份、月份、天來統計SQL
- Python實用技法第14篇:根據欄位將記錄分組:itertools.groupby()Python
- 指定快照時間內根據等待類查詢消耗較高的sqlSQL
- vue+element-ui根據時間查詢VueUI
- Laravel ORM 中,根據關聯查詢的欄位值,對主查詢排名LaravelORM
- swift4.0 物件資料來源根據屬性分組,時間排序Swift物件排序
- MySQL8 根據某屬性查詢欄位排名由自定義變數到rank()的變動MySql變數
- php 根據給定字串時間獲取時區PHP字串
- 如何在Clob欄位中查詢
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹
- python 根據時間戳建立目錄操作Python時間戳