将日期分割为Hive或SQL Server中的多个日期范围

问题描述 投票:0回答:2

我想将以下日期转换为不同的日期范围,此处emp属于2019年5月25日至2099-02-14年之间的钦奈地区,但介于emp之间,emp在2020-02-15年至2020年之间由DEL工作-02-23。

enter image description here

所以我想将以上日期转换为以下日期范围

enter image description here

sql sql-server hive hiveql
2个回答
0
投票

我已经在SQL Server中尝试过以下方法,并且可以使用:

测试设置

CREATE TABLE Employee(EmployeeId INT, fromDate date, todate date, Placename VARCHAR(100), PlaceCode VARCHAR(100))

INSERT INTO Employee
VALUES(1111,'2019-07-25','2099-02-14','CHENNAI','MAA'),
(1111,'2020-02-15','2020-02-23','DELHI','DEL');

要执行的查询

;WITH CTE_Ranges AS
(
SELECT EmployeeId, fromdate, lag(fromdate,1) OVER(PARTITION BY EmployeeId ORDER BY fromdate) previousfromDate,todate
, lead(todate,1) OVER(PARTITION BY EmployeeId ORDER BY todate) nexttodate, placename, placecode from Employee
)
--Handle the Maximum and minimum dates
SELECT * FROM 
(
SELECT EmployeeId, fromdate, DATEADD(day,-1,lead(fromdate) over(partition by EmployeeId ORDER BY fromDate)) as todate, PlaceName, PlaceCode
FROM CTE_Ranges
UNION ALL
SELECT EmployeeId, DATEADD(day,1,lag(todate) over(partition by EmployeeId ORDER BY todate)) as fromdate, todate,PlaceName, PlaceCode
FROM CTE_Ranges) AS t
WHERE fromdate is not null and todate is not null
UNION ALL
--Now handle normal date ranges
SELECT EmployeeId, fromDate,todate, placename, placecode
from cte_ranges
WHERE previousfromdate is not null and nexttodate is not null
order by fromdate

结果集

+------------+------------+------------+-----------+-----------+
| EmployeeId |  fromdate  |   todate   | PlaceName | PlaceCode |
+------------+------------+------------+-----------+-----------+
|       1111 | 2019-07-25 | 2020-02-14 | CHENNAI   | MAA       |
|       1111 | 2020-02-15 | 2020-02-23 | DELHI     | DEL       |
|       1111 | 2020-02-24 | 2099-02-14 | CHENNAI   | MAA       |
+------------+------------+------------+-----------+-----------+

0
投票

要处理多层嵌套,可以取消数据透视和

with e as (
      -- unpivot the dates
      select employeeid, fromdate as dte,
             placename, placecode
      from t
      union all
      select employeeid, enddate, null, null
      from t
     ),
     e2 as (
     -- impute the intermediate placenames
     select e.*,
            max(placename) over (partition by employeeid, grp) as imputed_placename
     from (select e.*,
                  count(placename) over (partition by employeeid order by dte) as grp
           from e
          ) e
    )
select employeeid, fromdate,
       dateadd(day, -1, lead(fromdate) over (partition by employeeid order by dte)) as enddate,
       placename, placecode
from e1;
© www.soinside.com 2019 - 2024. All rights reserved.