我们在这里遇到了巨大的挑战。我们假设第一只手中没有正确规划一个db的表。这就是它,我需要一个解决方案。
有一个包含2个字段的表A.我们认为我每天都有一位助理支持我的工作,但我刚刚开始帮助我时就注册了。这意味着每个助理的“停止日期”(表中不存在)是下一个助理的开始日期前一天。
./gradlew -DsomeProperty=true -q bootRun
还有第二张表B,用于记录我的助手工作了多少小时:
Assistant | Start Date
James | 07/01/17
Frank | 01/03/18
Erika | 01/06/18
根据上面的信息,我需要编写一个SQL来返回一个如下表所示的表,考虑每个人的开始日期:
Date | Worked Hours
12/31/17 | 7.5
01/01/18 | 7.5
01/02/18 | 9
01/03/18 | 8
01/04/18 | 9
01/05/18 | 7.5
01/06/18 | 9
01/07/18 | 10
基本上我需要以某种方式关联日期和开始日期以返回助手,但它涉及日期比较,我不知道该怎么做。
任何想法如何解决这个问题?
答案 0 :(得分:0)
您可以使用相关子查询:
select b.*,
(select a.assistant
from a
where a.date <= b.date
order by a.date desc
fetch first 1 row only
) as assistant
from b;
请注意,所有数据库都支持ANSI标准fetch first 1 row only
,因此您可能需要使用limit
或top
或适用于您的数据库的任何数据库。
答案 1 :(得分:0)
infinity
来保持最终间隔未闭合CREATE TABLE a
( assistant text primary key
, startdate date
);
SET datestyle = 'mdy';
insert into a(assistant,startdate) VALUES
('James', '07/01/17' )
,('Frank', '01/03/18' )
,('Erika', '01/06/18' )
;
CREATE TABLE b
( ddate DATE NOT NULL primary key
, workedhours DECIMAL(4,1)
);
insert into b(ddate,workedhours) VALUES
('12/31/17', 7.5)
,('01/01/18', 7.5)
,('01/02/18', 9)
,('01/03/18', 8)
,('01/04/18', 9)
,('01/05/18', 7.5)
,('01/06/18', 9)
,('01/07/18', 10)
;
WITH aa AS (
SELECT a.assistant
, a.startdate
, lead(a.startdate, 1, 'infinity'::date) OVER (ORDER BY a.startdate)
AS enddate
FROM a
)
-- SELECT * FROM a ;
SELECT aa.startdate, aa.enddate, aa.assistant
, SUM(b.workedhours) AS workedhours
FROM aa
LEFT JOIN b ON b.ddate >= aa.startdate
AND b.ddate < aa.enddate
GROUP BY 1,2,3
;
输出:
CREATE TABLE
SET
INSERT 0 3
CREATE TABLE
INSERT 0 8
startdate | enddate | assistant | workedhours
------------+------------+-----------+-------------
2017-07-01 | 2018-01-03 | James | 24.0
2018-01-03 | 2018-01-06 | Frank | 24.5
2018-01-06 | infinity | Erika | 19.0
(3 rows)
答案 2 :(得分:0)
你可以试试这个。
DECLARE @TableA TABLE (Assistant VARCHAR(10), [Start Date] DATE)
INSERT INTO @TableA VALUES
('James','07/01/17'),
('Frank','01/03/18'),
('Erika','01/06/18')
DECLARE @TableB TABLE ([Date] DATE, [Worked Hours] DECIMAL(18,2))
INSERT INTO @TableB VALUES
('12/31/17', 7.5),
('01/01/18', 7.5),
('01/02/18', 9 ),
('01/03/18', 8 ),
('01/04/18', 9 ),
('01/05/18', 7.5),
('01/06/18', 9 ),
('01/07/18', 10 )
;WITH CTE AS (
SELECT *, RN = ROW_NUMBER() OVER( PARTITION BY [Date] ORDER BY [Start Date] DESC)
FROM
@TableA A
INNER JOIN @TableB B ON A.[Start Date] <= B.Date
)
select Assistant, Date, [Worked Hours] FROM CTE WHERE RN = 1
结果:
Assistant Date Worked Hours
---------- ---------- ---------------------------------------
James 2017-12-31 7.50
James 2018-01-01 7.50
James 2018-01-02 9.00
Frank 2018-01-03 8.00
Frank 2018-01-04 9.00
Frank 2018-01-05 7.50
Erika 2018-01-06 9.00
Erika 2018-01-07 10.00