Mysql 连接两个表,其中表A具有日期值,并且需要在B中查找A中日期以下的下一个日期

Mysql 连接两个表,其中表A具有日期值,并且需要在B中查找A中日期以下的下一个日期,mysql,sql,greatest-n-per-group,Mysql,Sql,Greatest N Per Group,我有一张桌子: | id | date | =================== | 1 | 2010-01-13 | | 2 | 2011-04-19 | | 3 | 2011-05-07 | | .. | ... | 表B: | date | value | ====================== | 2009-03-29 | 0.5 | | 2010-01-30 | 0.55 | | 2011-08-12 | 0.67 | 现

我有一张桌子:

| id | date       |
===================
| 1  | 2010-01-13 |
| 2  | 2011-04-19 |
| 3  | 2011-05-07 |
| .. | ...        |
表B:

| date       | value |
======================
| 2009-03-29 | 0.5   |
| 2010-01-30 | 0.55  |
| 2011-08-12 | 0.67  |
现在,我正在寻找一种方法来连接这两个表,将B中的value列映射到a中的日期。对于我来说,这里比较棘手的部分是,表B只存储更改日期和新值。现在,当我在表A中需要这个值时,SQL需要返回它请求该值的下一个日期

因此,这些表的连接最终应如下所示:

| id | date       | value |
===========================
| 1  | 2010-01-13 | 0.5   |
| 2  | 2011-04-19 | 0.55  |
| 3  | 2011-05-07 | 0.55  |
| .. | ...        | ...   |

如何执行此操作?

您可以使用限制为1的子查询在表B中查找最新值:

select  id
,       date
,       (
        select  value
        from    B
        where   B.date < A.date
        order by
                B.date desc
        limit   1
        ) as value
from    A

您可以使用限制为1的子查询查找表B中的最新值:

select  id
,       date
,       (
        select  value
        from    B
        where   B.date < A.date
        order by
                B.date desc
        limit   1
        ) as value
from    A
我们正在做的是:

对于id_date表中的每个日期,请选择表A, 我们在日期表B中找到日期 哪个日期是date_val表中的最高日期,但仍然小于id_date.date 我们正在做的是:

对于id_date表中的每个日期,请选择表A, 我们在日期表B中找到日期 哪个日期是date_val表中的最高日期,但仍然小于id_date.date
当两个表中至少有一个匹配项时,内部联接返回行。试试这个

Select A.id,A.date,b.value 
from A inner join B 
on A.date=b.date 

当两个表中至少有一个匹配项时,内部联接返回行。试试这个

Select A.id,A.date,b.value 
from A inner join B 
on A.date=b.date 

我受到了其他答案的启发,但最后使用常用表格表达式给出了自己的解决方案:

WITH datecombination (id, adate, bdate) AS 
(
SELECT id, A.date, MAX(B.Date) as Bdate
FROM tableA A
LEFT JOIN tableB B
ON B.date <= A.date
GROUP BY A.id, A.date
)
SELECT DC.id, DC.adate, B.value FROM datecombination DC
LEFT JOIN tableB B
ON DC.bdate = B.bdate 

我受到了其他答案的启发,但最后使用常用表格表达式给出了自己的解决方案:

WITH datecombination (id, adate, bdate) AS 
(
SELECT id, A.date, MAX(B.Date) as Bdate
FROM tableA A
LEFT JOIN tableB B
ON B.date <= A.date
GROUP BY A.id, A.date
)
SELECT DC.id, DC.adate, B.value FROM datecombination DC
LEFT JOIN tableB B
ON DC.bdate = B.bdate 

对于B与a的关系,我有点困惑-您是否在寻找B中的下一个日期,该日期在a中的某个日期之后,该日期将使示例的第一行为0.55而不是0.5?请澄清,您希望使用B中的上限日期小于或等于a的日期来加入a和B?是吗?不,B中的日期必须是@Benjamin:很高兴你这样问-它会给出比填充一个稀疏表更好的解决方案,而不是填充一个实际不需要的表格:我有点困惑B与a的关系-你是在寻找B中的下一个日期,它在a中的日期之后,会使示例的第一行变成0.55而不是0.5吗?只是为了说明一下清楚,是否要使用B中小于或等于A日期的上限日期加入A和B?是吗?不,B中的日期必须是@Benjamin:很高兴你这样问-它将提供比填充一个稀疏表更好的解决方案,而不是填充一个实际上不需要的表:你的查询将不起作用,他们正在查找与表A中的日期最接近的匹配项。如果您查看的日期与表B中的日期都不匹配,但预期输出会显示这些日期的值。您的查询将不起作用,他们正在查找与表A中的日期最接近的匹配项。如果查看这些日期,其中没有一个与表B匹配,但预期输出会显示它们的值。