基于最近时间戳连接两个表的 SQL 查询 [英] SQL Query to Join Two Tables Based Off Closest Timestamp

查看:24
本文介绍了基于最近时间戳连接两个表的 SQL 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 SQL 中有两个表,我需要能够根据表 B 中早于或等于表 A 中的时间戳的时间戳进行连接.

所以,这里有两个表的一些假数据和所需的输出:

已结案(表 A)

<上一页>|编号 |分辨率 |时间戳 |------------------------------------------------|1 |解决了|2006-10-05 11:55:44.888153 ||2 |关闭|2007-10-07 12:34:17.033498 ||3 |垃圾|2008-10-09 08:19:36.983747 ||4 |解决了|2010-10-13 04:28:14.348753 |

分类(表 B)

<上一页>|编号 |价值 |时间戳 |-------------------------------------------------|1 |大一|2006-01-01 12:02:44.888153 ||2 |大二 |2007-01-01 12:01:19.984333 ||3 |初中 |2008-01-01 12:02:28.746149 |

期望的结果

<上一页>|编号 |分辨率 |时间戳 |价值 |--------------------------------------------------------------|1 |解决了|2006-10-05 11:55:44.888153 |大一||2 |关闭|2007-10-07 12:34:17.033498 |大二 ||3 |垃圾|2008-10-09 08:19:36.983747 |初中 ||4 |解决了|2010-10-13 04:28:14.348753 |初中 |

所以,我知道代码需要如下所示,我只是不知道如何处理 JOINON 部分($1 和$2 是要传入的变量):

选择 case.id、case.resolution、case.timestamp、class.valueFROM closed_cases 作为案例LEFT JOIN 分类作为类 ON ???WHERE case.timestamp BETWEEN $1 和 $2;

我知道我可以使用子选择,但这将在至少几千行上运行,可能更多,而且我需要它非常快;所以我希望有一个简单的子句可以做到这一点.

解决方案

如果您可以更改表结构,我建议更改分类表以包含结束日期和开始日期 - 这会容易得多以这种方式加入表格.

如果没有,我建议如下:

选择 case.id、case.resolution、case.timestamp、class.valueFROM closed_cases 作为案例左连接(选择 c.*,(选择分钟(时间戳)从分类 c1其中c1.timestamp>c.timestamp) 时间结束来自分类 c) AS 类ON case.timestamp >= class.timestamp 和(case.timestamp < class.timeend 或 class.timeend IS NULL)WHERE case.timestamp BETWEEN $1 和 $2;

编辑 - 分类结束日期:

选择 case.id、case.resolution、case.timestamp、class.valueFROM closed_cases 作为案例LEFT JOIN 分类 AS 类ON case.timestamp >= class.timestamp 和 case.timestamp <类.timeendWHERE case.timestamp BETWEEN $1 和 $2;

I have two tables in SQL and I need to be able to do a join based off of the timestamp in table B that is earlier than or equal to the timestamp in table A.

So, here is some fake data for two tables and the desired output:

Closed Cases (Table A)

| id | resolution |         timestamp          |
------------------------------------------------
|  1 |     solved | 2006-10-05 11:55:44.888153 |
|  2 |     closed | 2007-10-07 12:34:17.033498 |
|  3 |    trashed | 2008-10-09 08:19:36.983747 |
|  4 |     solved | 2010-10-13 04:28:14.348753 |

Classification (Table B)


| id |    value    |         timestamp          |
-------------------------------------------------
|  1 |    freshman | 2006-01-01 12:02:44.888153 |
|  2 |   sophomore | 2007-01-01 12:01:19.984333 |
|  3 |      junior | 2008-01-01 12:02:28.746149 |

Desired Results

| id | resolution |         timestamp          |    value    |
--------------------------------------------------------------
|  1 |     solved | 2006-10-05 11:55:44.888153 |    freshman |
|  2 |     closed | 2007-10-07 12:34:17.033498 |   sophomore |
|  3 |    trashed | 2008-10-09 08:19:36.983747 |      junior |
|  4 |     solved | 2010-10-13 04:28:14.348753 |      junior |

So, I know the code needs to look like the following, I just can't figure out what to do with the ON portion of the JOIN ($1 and $2 are variables that will be passed in):

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN classifications AS class ON ???
  WHERE case.timestamp BETWEEN $1 AND $2;

I know I could use a sub-select, but this will be operating on at least a few thousand rows, probably more, and I need it to be really fast; so I was hoping for a simple clause that could do it.

解决方案

If you can make changes to the table structures, I recommend changing the classification table to include an end date as well as a start date - it will be much easier to join to the table that way.

If not, I suggest the following:

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN (select c.*, 
                    (select min(timestamp)
                     from classifications c1
                      where c1.timestamp > c.timestamp) timeend
             from classifications c) AS class 
  ON case.timestamp >= class.timestamp and 
     (case.timestamp < class.timeend or class.timeend IS NULL)
  WHERE case.timestamp BETWEEN $1 AND $2;

EDIT - with the end date on classification:

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN classifications AS class 
  ON case.timestamp >= class.timestamp and case.timestamp < class.timeend
  WHERE case.timestamp BETWEEN $1 AND $2;

这篇关于基于最近时间戳连接两个表的 SQL 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆