具有多个日期条件的SQL JOIN

时间:2018-01-04 16:48:26

标签: sql join

我们有第一个 valuetable 表,查询应检查是否存在 可纠正表中的下一个较年轻的日期时间,并应使用 corrdatetime 添加 corrvalue

我的问题查询:

SELECT * FROM valuetable vt
LEFT JOIN correctiontable corr ON corr.value_id = vt.id WHERE vt.datetime <= corr.corrdatetime

刚刚提供最后的corrdatetime ......

澄清结果:

  • Row1 id1 应为NULL,因为有价值的日期时间小于更正日期时间
  • 第2行id2 01/08/2017 00:00:00 ,因为有价值的日期时间比 01/12/2017更年轻但更年轻10:00:00 corrdatetime
  • Row3 id2 01/12/2017 10:00:00
  • 进行了修正
  • Row4 id3 为NULL,校正表中没有corrdatetime

谢谢大家++

+----------------------------------+
|            valuetable            |
+----------------------------------+
| id | datetime            | value |
+----+---------------------+-------+
| 1  | 22/07/2017 13:00:00 | 123   |
+----+---------------------+-------+
| 2  | 10/08/2017 09:00:00 | 456   |
+----+---------------------+-------+
| 2  | 05/12/2017 20:00:00 | 789   |
+----+---------------------+-------+
| 3  | 11/11/2017 11:11:11 | 012   |
+----+---------------------+-------+
+-------------------------------------------------+
|                 correctiontable                 |
+-------------------------------------------------+
| id | value_id | corrdatetime        | corrvalue |
+----+----------+---------------------+-----------+
| 1  | 2        | 01/08/2017 00:00:00 | 888       |
+----+----------+---------------------+-----------+
| 2  | 2        | 01/12/2017 10:00:00 | 999       |
+----+----------+---------------------+-----------+
| 3  | 1        | 01/08/2017 20:00:00 | 111       |
+----+----------+---------------------+-----------+
+--------------------------------------------------------------------+
|                               Result (as it should be)             |
+--------------------------------------------------------------------+
| id | datetime            | corrdatetime        | value | corrvalue |
+----+---------------------+---------------------+-------+-----------+
| 1  | 22/07/2017 13:00:00 | NULL                | 123   | NULL      |
+----+---------------------+---------------------+-------+-----------+
| 2  | 10/08/2017 09:00:00 | 01/08/2017 00:00:00 | 456   | 888       |
+----+---------------------+---------------------+-------+-----------+
| 2  | 05/12/2017 20:00:00 | 01/12/2017 10:00:00 | 789   | 999       |
+----+---------------------+---------------------+-------+-----------+
| 3  | 11/11/2017 11:11:11 | NULL                | 012   | NULL      |
+----+---------------------+---------------------+-------+-----------+

3 个答案:

答案 0 :(得分:1)

假设“年轻”意味着“逻辑上小于”,这应该适合你。

select *
    from valuetable a
    outer apply (
        select top 1 *
            from correctiontable y
            where y.value_id = a.id
                and y.datetime < a.datetime
            order by y.datetime desc
    ) b

答案 1 :(得分:0)

非常感谢@KindaTechy为我提供了正确的道路!

我创建了两个查询,一个用于MySQL,一个用于&gt; = Oracle 12.1

对于MySQL:

SELECT *
  FROM valuetable vt
  LEFT JOIN correctiontable ON correctiontable.id
    =
    (SELECT corr.id
     FROM correctiontable corr
     WHERE vt.id = corr.value_id
      AND vt.datetime <= corr.corrdatetime
     ORDER BY datetime DESC
     LIMIT 1)

对于Oracle:

select *
    from valuetable vt
    outer apply (
        select *
            from correctiontable corr
            where corr.value_id = vt.id
                and corr.corrdatetime < vt.datetime
            order by corr.corrdatetime desc
            FETCH FIRST 1 ROWS ONLY
    ) b;

答案 2 :(得分:-1)

我找到了一个有效的查询,但id valuetableSELECT vt.id, vt.datetime, corr.corrdatetime, vt.value, corr.corrvalue FROM valuetable vt LEFT JOIN correctiontable corr ON corr.value_id = vt.id AND vt.datetime >= corr.corrdatetime 应该是唯一的,否则你会得到一个交叉产品。

WHERE-CLAUSE

通过将日期约束从ON-CLAUSE更改为{{1}},它只会影响加入,而不会影响结果。

为您制作样本http://sqlfiddle.com/#!9/301a6/4/0

需要非唯一ID时,必须改进查询。还有测试数据集。