![](/img/trans.png)
[英]how to get values using again MAX and MIN function in oracle sql?
[英]How to get the values based on min and max date in groups in oracle?
我有一個表,其中包含這樣的數據:
車輛 | 開始 | 結尾 | 日期 |
---|---|---|---|
卡車A | 一種 | 乙 | 02/01/2021 01:00:00 |
卡車A | 乙 | C | 02/01/2021 02:00:00 |
卡車A | C | D | 04/01/2021 03:00:00 |
卡車B | C | 一種 | 05/01/2021 01:00:00 |
卡車B | 一種 | 乙 | 06/01/2021 01:00:00 |
卡車 C | C | 乙 | 07/01/2021 01:00:00 |
卡車 C | 乙 | C | 08/01/2021 01:00:00 |
卡車 C | C | 乙 | 09/01/2021 01:00:00 |
卡車 C | 乙 | 一種 | 10/01/2021 01:00:00 |
我需要根據日期獲取每輛車的起點和終點。
例如,卡車 A 在 02/01/2021 01:00:00 從 A 點出發到 B 點。 然后卡車 A 在 02/01/2021 02:00:00 從 B 點移動到 C 點。 卡車 A 已於 04/01/2021 03:00:00 從 C 點移動到 D 點。
它從 A 點開始,在 D 點結束。
我想得到這樣的結果:
車輛 | 開始 | 結尾 | 日期 |
---|---|---|---|
卡車A | 一種 | D | 04/01/2021 03:00:00 |
使用GROUP BY
並使用KEEP
聚合以獲取FIRST
或LAST
日期值:
SELECT vehicle,
MIN("START") KEEP (DENSE_RANK FIRST ORDER BY "DATE") AS "START",
MAX("END") KEEP (DENSE_RANK LAST ORDER BY "DATE") AS "END",
MAX("DATE") AS "DATE"
FROM table_name
GROUP BY vehicle
其中,對於樣本數據:
CREATE TABLE table_name (Vehicle, "START", "END", "DATE") AS
SELECT 'Truck A', 'A', 'B', DATE '2021-01-02' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck A', 'B', 'C', DATE '2021-01-02' + INTERVAL '2' HOUR FROM DUAL UNION ALL
SELECT 'Truck A', 'C', 'D', DATE '2021-01-04' + INTERVAL '3' HOUR FROM DUAL UNION ALL
SELECT 'Truck B', 'C', 'A', DATE '2021-01-05' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck B', 'A', 'B', DATE '2021-01-06' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'C', 'B', DATE '2021-01-07' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'B', 'C', DATE '2021-01-08' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'C', 'B', DATE '2021-01-09' + INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'B', 'A', DATE '2021-01-10' + INTERVAL '1' HOUR FROM DUAL
輸出:
車輛 開始 結尾 日期 卡車A 一種 D 2021-01-04 03:00:00 卡車B C 乙 2021-01-06 01:00:00 卡車 C C 一種 2021-01-10 01:00:00
db<> 在這里小提琴
WITH CTE(Vehicle, StartT, EndD, DateD) AS
(
SELECT 'Truck A', 'A' ,'B', CAST('02/01/2021 01:00:00'AS SMALLDATETIME) UNION ALL
SELECT'Truck A' , 'B', 'C', CAST('02/01/2021 02:00:00'AS SMALLDATETIME) UNION ALL
SELECT'Truck A', 'C' , 'D', '04/01/2021 03:00:00' UNION ALL
SELECT'Truck B', 'C' , 'A', '05/01/2021 01:00:00' UNION ALL
SELECT'Truck B', 'A', 'B', '06/01/2021 01:00:00' UNION ALL
SELECT'Truck C', 'C' , 'B', '07/01/2021 01:00:00' UNION ALL
SELECT'Truck C' , 'B', 'C', '08/01/2021 01:00:00' UNION ALL
SELECT'Truck C' , 'C' , 'B', '09/01/2021 01:00:00' UNION ALL
SELECT'Truck C' , 'B', 'A', '10/01/2021 01:00:00'
),
CTE2(Vehicle, StartT, EndD, DateD,XCOL,YCOL) AS
(
SELECT C.Vehicle,C.STARTT,C.ENDD,C.DATED,
ROW_NUMBER()OVER(PARTITION BY C.Vehicle ORDER BY C.DATED ASC)XCOL,
ROW_NUMBER()OVER(PARTITION BY C.Vehicle ORDER BY C.DATED DESC)YCOL
FROM CTE AS C
)
SELECT C.VEHICLE,C.StartT,X.EndD,X.DateD
FROM CTE2 AS C
JOIN CTE2 AS X ON C.Vehicle=X.Vehicle
WHERE C.XCOL=1 AND X.YCOL=1
抱歉,我沒有 Oracle,因此創建了 MS SQL Server CTE 查詢表示您的示例數據 CTE2 計算“雙向”row_number。 對於起始行(例如對於 'TruckA')XCOL=1。 對於 end row YCOL=1 然后我們在 Vehicle 上加入這兩個 CTE。 你能試試這個查詢是否適合你
我認為這個解決方案應該適合你,盡管可能有一個更優雅的解決方案。
with x ( Vehicle , Start_Letter ,End_Letter , Date_Letter )
as
(
select 'Truck A' , 'A' , 'B' , to_date('02/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck A' , 'B' , 'C' , to_date('02/01/2021 02:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck A' , 'C' , 'D' , to_date('04/01/2021 03:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck B' , 'C' , 'A' , to_date('05/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck B' , 'A' , 'B' , to_date('06/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck C' , 'C' , 'B' , to_date('07/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck C' , 'B' , 'C' , to_date('08/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck C' , 'C' , 'B' , to_date('09/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual union all
select 'Truck C' , 'B' , 'A' , to_date('10/01/2021 01:00:00','dd/mm/yyyy hh24:mi:ss') from dual
)
select vehicle , start_letter, end_letter, date_letter from
(
select vehicle , min_start_lett as start_letter, max_start_lett as end_letter, date_letter,
row_number() over(partition by vehicle order by date_letter desc) as ranking
from
(
select x.* ,
rank() over(partition by vehicle order by start_letter desc, end_letter desc, date_letter desc ) as rn ,
min(start_letter) over(partition by vehicle) as min_start_lett ,
max(end_letter) over(partition by vehicle) as max_start_lett
from x
) d
where rn = ( select max(rn) from x c where c.vehicle = d.vehicle group by vehicle )
) where ranking = 1
;
使用窗函數 FIRST_VALUE 查找每輛車的第一個和最后一個
SELECT Vehicle
, FirstStart AS "Start"
, LastEnd AS "End"
, MAX("Date") AS "Date"
FROM
(
SELECT Vehicle, "Start", "End", "Date"
, FIRST_VALUE("Start") OVER (PARTITION BY Vehicle ORDER BY "Date") AS FirstStart
, FIRST_VALUE("End") OVER (PARTITION BY Vehicle ORDER BY "Date" DESC) AS LastEnd
FROM yourtable
) q
GROUP BY Vehicle, FirstStart, LastEnd
ORDER BY Vehicle;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.