与日期约束的字段相关

时间:2018-01-25 13:45:38

标签: sql date constraints correlation date-comparison

我们在这里遇到了巨大的挑战。我们假设第一只手中没有正确规划一个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

基本上我需要以某种方式关联日期和开始日期以返回助手,但它涉及日期比较,我不知道该怎么做。

任何想法如何解决这个问题?

3 个答案:

答案 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,因此您可能需要使用limittop或适用于您的数据库的任何数据库。

答案 1 :(得分:0)

  • 使用&#39; lead()&#39;找到下一个记录
  • 使用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