sql - 根据另一条记录中的日期加入最近的记录

标签 sql postgresql date greatest-n-per-group

我有两个表 - 我们称它们为 weekcontract,如下所示:

Week                                    Contract    
emp_id | starting   | data1 |  ...   emp_id | from_date  | data2 | ...
-------|------------|-------|--      -------|------------|-------|--
12     | 2019-01-08 | abcd  |        12     | 2018-08-01 | efgh  | 
12     | 2019-01-15 | abcd  |        13     | 2018-10-02 | efgh  | 
12     | 2019-01-22 | abcd  |        13     | 2019-01-15 | ijkl  | 
13     | 2019-01-08 | abcd  |        13     | 2019-03-19 | mnop  | 
13     | 2019-01-15 | abcd  |        14     | 2017-02-02 | efgh  | 
13     | 2019-01-22 | abcd  |        15     | 2018-01-19 | efgh  | 

week.starting 字段是一个相当固定的日期(时间设置为午夜的日期时间)。 (emp_id, starting) 的具体组合是唯一的。 from_date字段也是一个日期,记录了contract记录适用的开始时间。这可能是在未来,所以我们不能只做一个 MAX(from) 并为每个员工获得正确的契约(Contract)。目前,(emp_id, from_date) 是唯一的,但我不想依赖它。 week.startingcontract.from_date 可以相同。

我想要一个返回整个 week 记录的查询,并且对于每个 contract 当时处于事件状态的记录 - 即 from_date 最大,但仍小于或等于 week.starting。如果我有特定的一周,获得这份契约(Contract)是一个非常简单的最大 n-per-group 问题:

SELECT * FROM contract 
WHERE contract.emp_id = @emp_id AND contract.from_date <= @starting
ORDER BY contract.from_date DESC
LIMIT 1

但我不知道如何将此作为查询的一部分来获取 week 中的每条记录。我的具体障碍组合意味着我无法找到答案,尽管这是一组常见的问题。我似乎无法将 week.starting 传递到子查询中,而且我似乎也无法在连接中使用 LIMIT。到目前为止,我最好的尝试是加入所有不到给定一周的契约(Contract)。

什么查询会返回我要查找的结果?

emp_id | starting   | from_date  | data1 | data2 | ...
-------|------------|------------|-------|-------|--
12     | 2019-01-08 | 2018-08-01 | abcd  | efgh  |
12     | 2019-01-15 | 2018-08-01 | abcd  | efgh  |
12     | 2019-01-22 | 2018-08-01 | abcd  | efgh  |
13     | 2019-01-08 | 2018-10-02 | abcd  | efgh  |
13     | 2019-01-15 | 2019-01-15 | abcd  | ijkl  |
13     | 2019-01-22 | 2019-01-15 | abcd  | ijkl  |

最佳答案

您应该能够使用窗口函数在过滤 future 合约并分配排名后及时对合约进行排序。然后你可以选择排名靠前的最新的。

尚未对此进行测试,但应该类似于:

select * from (
    select w.*, c.from_date, c.data2,
        row_number() over (partition by c.emp_id, w.starting order by c.from_date desc) as latest
    from week w
    join contract c on c.emp_id = w.emp_id and c.from_date <= w.starting
) as sub where latest = 1

关于sql - 根据另一条记录中的日期加入最近的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56353800/

相关文章:

php - 选择列 FROM table_name WHERE username=$_SESSION ['username' ] 不起作用

c - PostgreSQL C函数,如何返回文本数组

sql - 按范围分组以包括没有值的范围

java - 将儒略日期转换为以毫秒为单位的时间

java - 处理 Java 日期格式的不可理解的行为。

mysql - 两天之间的日期

mysql - 当其他表可以使用联接连接时,在单个表中拥有多个外键是好还是坏?

sql - 很难合并 jsonb 对象数组和列

php - MySQL UNIX_TIMESTAMP 行为怪异

社交网络的 SQL 建模追随者/追随者关系