我有两个表 - 我们称它们为 week
和 contract
,如下所示:
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.starting
和 contract.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/