如何 select 只有最近的时间戳?
How to select only the most recent timestamp?
如果我对多个 table 执行内部联接,我如何确保结果集只包含最新的时间戳。例如
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
#MOST RECENT TIMESTAMP from car.updated_on, motorcycle.updated_on or walkc.updated_on
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id
WHERE
e.event_id = c.event_id
AND e.event_id = m.event_id
AND e.event_id = w.event_id
我有一个 table 记录所有发生的事件,我只想提取最近的时间戳,而不管所有三个事件(汽车、摩托车或步行)中的所有客户的事件类型).
示例数据:
事件
customer_id
event_id
1
100
2
101
3
102
4
103
5
104
6
105
7
106
8
107
9
108
10
109
汽车
customer_id
event_id
car_id
updated_on
1
100
1
2021-07-2310:09:05
2
101
1
2021-07-2310:09:05
3
102
1
2021-07-2310:09:05
4
103
1
2021-07-2310:09:05
5
104
1
2021-07-2310:09:05
6
105
1
2021-07-2310:09:05
7
106
1
2021-07-2310:09:05
8
107
1
2021-07-2310:09:05
9
108
1
2021-07-2310:09:05
10
109
1
2021-07-2310:09:05
摩托车
customer_id
event_id
motorcycle_id
updated_on
1
100
1
2021-07-2310:09:00
2
101
1
2021-07-2310:09:00
3
102
1
2021-07-2310:09:00
4
103
1
2021-07-2310:09:00
5
104
1
2021-07-2310:09:10
6
105
1
2021-07-2310:09:10
7
106
1
2021-07-2310:09:00
8
107
1
2021-07-2310:09:00
走路
customer_id
event_id
walk_id
updated_on
1
100
1
2021-07-2310:09:00
2
101
1
2021-07-2310:09:00
3
102
1
2021-07-2310:09:00
4
103
1
2021-07-2310:09:00
5
104
1
2021-07-2310:09:00
6
105
1
2021-07-2310:09:00
7
106
1
2021-07-2310:09:00
8
107
1
2021-07-2310:09:15
9
108
1
2021-07-2310:09:15
想要的结果:
customer_id
event_id
updated_on
评论
1
100
2021-07-2310:09:05
车内TS
2
101
2021-07-2310:09:05
车内TS
3
102
2021-07-2310:09:05
车内TS
4
103
2021-07-2310:09:05
车内TS
5
104
2021-07-2310:09:10
摩托车上的TS
6
105
2021-07-2310:09:10
摩托车上的TS
7
106
2021-07-2310:09:15
行走中的 TS
8
107
2021-07-2310:09:15
行走中的 TS
我不需要最终结果集中的comment
,我添加它只是为了解释目的。实际上,我不在乎事件是什么。我只关心四个 table 中的 INNER JOIN
;所以最多应该只有 8 条记录,我只想要最新(最高)的时间戳值。 customer_id
和 event_id
需要匹配所有 INNER JOINS
.
例如:customer_id = 1
和 event_id = 100
;这存在于所有 4 table 中。它具有 updated_on
的三个值(分别来自:汽车、摩托车和步行)。我想要 MAX(2021-07-23 10:09:05, 2021-07-23 10:09:00, 2021-07-23 10:09:00)
; MAX(car.updated_on, motorcyle.updated_on, walk.updated_on)
.
如有任何帮助,我们将不胜感激。
编辑:我在两个查询中得到了想要的结果。希望优化成单个查询。
- 仅获取三个 table 之间的
UNIQUE
条记录,并将它们存储在另一个名为 event_joined
的位置。 table 每次都被完全覆盖,而不仅仅是附加到。
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id
WHERE
e.event_id = c.event_id
AND e.event_id = m.event_id
AND e.event_id = w.event_id
- 在执行
UNION
之前,我们知道所有三个 table 都将具有相同的行数,因为我们之前加入它们只是为了匹配记录。现在我们只需 GROUP BY
并获得 MAX
(最近的)时间戳。
SELECT event_temp.customer_id, event_temp.event_id, MAX(event_temp.updated_on) AS updated_on
FROM (
SELECT customer_id, event_id, updated_on FROM car AS c INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
UNION ALL
SELECT customer_id, event_id, updated_on FROM motorcycle AS m INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
UNION ALL
SELECT customer_id, event_id, updated_on FROM walk AS w INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
) AS event_temp
GROUP BY event_temp.customer_id, event_temp.event_id;
有什么方法可以将其优化为单个查询吗?谢谢。
您可以使用 CROSS APPLY 进行简单查询,如下所示:
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
max(t.updated_On)
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id and e.event_id = c.event_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id and e.event_id = m.event_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id and e.event_id = w.event_id
CROSS APPLY (values (c.updated_On),(m.updated_On),(w.updated_On)) as t(updated_On)
GROUP BY e.customer_id,
e.event_id
示例数据和工作解决方案
declare @event table(cust_id int, event_id int)
declare @car table(cust_id int, event_id int, updated_on datetime)
declare @walk table(cust_id int, event_id int, updated_on datetime)
insert into @event values (1, 100)
insert into @car values (1,100, '2020-01-01')
insert into @walk values(1,100, '2020-02-01')
SELECT
e.cust_id AS customer_id,
e.event_id AS event_id,
max(t.updatedON) as recent_timestamp
FROM
@event AS e
INNER JOIN @car AS c ON e.cust_id = c.cust_id and e.event_id = c.event_id
INNER JOIN @walk AS w ON e.cust_id = w.cust_id and e.event_id = w.event_id
CROSS APPLY (values(c.updated_On),(w.updated_on)) as t(updatedOn)
group by e.cust_id, e.event_id
customer_id
event_id
recent_timestamp
1
100
2020-02-01 00:00:00.000
如果我对多个 table 执行内部联接,我如何确保结果集只包含最新的时间戳。例如
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
#MOST RECENT TIMESTAMP from car.updated_on, motorcycle.updated_on or walkc.updated_on
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id
WHERE
e.event_id = c.event_id
AND e.event_id = m.event_id
AND e.event_id = w.event_id
我有一个 table 记录所有发生的事件,我只想提取最近的时间戳,而不管所有三个事件(汽车、摩托车或步行)中的所有客户的事件类型).
示例数据:
事件
customer_id | event_id |
---|---|
1 | 100 |
2 | 101 |
3 | 102 |
4 | 103 |
5 | 104 |
6 | 105 |
7 | 106 |
8 | 107 |
9 | 108 |
10 | 109 |
汽车
customer_id | event_id | car_id | updated_on |
---|---|---|---|
1 | 100 | 1 | 2021-07-2310:09:05 |
2 | 101 | 1 | 2021-07-2310:09:05 |
3 | 102 | 1 | 2021-07-2310:09:05 |
4 | 103 | 1 | 2021-07-2310:09:05 |
5 | 104 | 1 | 2021-07-2310:09:05 |
6 | 105 | 1 | 2021-07-2310:09:05 |
7 | 106 | 1 | 2021-07-2310:09:05 |
8 | 107 | 1 | 2021-07-2310:09:05 |
9 | 108 | 1 | 2021-07-2310:09:05 |
10 | 109 | 1 | 2021-07-2310:09:05 |
摩托车
customer_id | event_id | motorcycle_id | updated_on |
---|---|---|---|
1 | 100 | 1 | 2021-07-2310:09:00 |
2 | 101 | 1 | 2021-07-2310:09:00 |
3 | 102 | 1 | 2021-07-2310:09:00 |
4 | 103 | 1 | 2021-07-2310:09:00 |
5 | 104 | 1 | 2021-07-2310:09:10 |
6 | 105 | 1 | 2021-07-2310:09:10 |
7 | 106 | 1 | 2021-07-2310:09:00 |
8 | 107 | 1 | 2021-07-2310:09:00 |
走路
customer_id | event_id | walk_id | updated_on |
---|---|---|---|
1 | 100 | 1 | 2021-07-2310:09:00 |
2 | 101 | 1 | 2021-07-2310:09:00 |
3 | 102 | 1 | 2021-07-2310:09:00 |
4 | 103 | 1 | 2021-07-2310:09:00 |
5 | 104 | 1 | 2021-07-2310:09:00 |
6 | 105 | 1 | 2021-07-2310:09:00 |
7 | 106 | 1 | 2021-07-2310:09:00 |
8 | 107 | 1 | 2021-07-2310:09:15 |
9 | 108 | 1 | 2021-07-2310:09:15 |
想要的结果:
customer_id | event_id | updated_on | 评论 |
---|---|---|---|
1 | 100 | 2021-07-2310:09:05 | 车内TS |
2 | 101 | 2021-07-2310:09:05 | 车内TS |
3 | 102 | 2021-07-2310:09:05 | 车内TS |
4 | 103 | 2021-07-2310:09:05 | 车内TS |
5 | 104 | 2021-07-2310:09:10 | 摩托车上的TS |
6 | 105 | 2021-07-2310:09:10 | 摩托车上的TS |
7 | 106 | 2021-07-2310:09:15 | 行走中的 TS |
8 | 107 | 2021-07-2310:09:15 | 行走中的 TS |
我不需要最终结果集中的comment
,我添加它只是为了解释目的。实际上,我不在乎事件是什么。我只关心四个 table 中的 INNER JOIN
;所以最多应该只有 8 条记录,我只想要最新(最高)的时间戳值。 customer_id
和 event_id
需要匹配所有 INNER JOINS
.
例如:customer_id = 1
和 event_id = 100
;这存在于所有 4 table 中。它具有 updated_on
的三个值(分别来自:汽车、摩托车和步行)。我想要 MAX(2021-07-23 10:09:05, 2021-07-23 10:09:00, 2021-07-23 10:09:00)
; MAX(car.updated_on, motorcyle.updated_on, walk.updated_on)
.
如有任何帮助,我们将不胜感激。
编辑:我在两个查询中得到了想要的结果。希望优化成单个查询。
- 仅获取三个 table 之间的
UNIQUE
条记录,并将它们存储在另一个名为event_joined
的位置。 table 每次都被完全覆盖,而不仅仅是附加到。
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id
WHERE
e.event_id = c.event_id
AND e.event_id = m.event_id
AND e.event_id = w.event_id
- 在执行
UNION
之前,我们知道所有三个 table 都将具有相同的行数,因为我们之前加入它们只是为了匹配记录。现在我们只需GROUP BY
并获得MAX
(最近的)时间戳。
SELECT event_temp.customer_id, event_temp.event_id, MAX(event_temp.updated_on) AS updated_on
FROM (
SELECT customer_id, event_id, updated_on FROM car AS c INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
UNION ALL
SELECT customer_id, event_id, updated_on FROM motorcycle AS m INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
UNION ALL
SELECT customer_id, event_id, updated_on FROM walk AS w INNER JOIN event_joined AS ej ON e.customer_id = c.customer_id AND e.event_id = c.event_id
) AS event_temp
GROUP BY event_temp.customer_id, event_temp.event_id;
有什么方法可以将其优化为单个查询吗?谢谢。
您可以使用 CROSS APPLY 进行简单查询,如下所示:
SELECT
e.customer_id AS customer_id,
e.event_id AS event_id,
max(t.updated_On)
FROM
event_table AS e
INNER JOIN car AS c ON e.customer_id = c.customer_id and e.event_id = c.event_id
INNER JOIN motorcycle AS m ON e.customer_id = m.customer_id and e.event_id = m.event_id
INNER JOIN walk AS w ON e.customer_id = w.customer_id and e.event_id = w.event_id
CROSS APPLY (values (c.updated_On),(m.updated_On),(w.updated_On)) as t(updated_On)
GROUP BY e.customer_id,
e.event_id
示例数据和工作解决方案
declare @event table(cust_id int, event_id int)
declare @car table(cust_id int, event_id int, updated_on datetime)
declare @walk table(cust_id int, event_id int, updated_on datetime)
insert into @event values (1, 100)
insert into @car values (1,100, '2020-01-01')
insert into @walk values(1,100, '2020-02-01')
SELECT
e.cust_id AS customer_id,
e.event_id AS event_id,
max(t.updatedON) as recent_timestamp
FROM
@event AS e
INNER JOIN @car AS c ON e.cust_id = c.cust_id and e.event_id = c.event_id
INNER JOIN @walk AS w ON e.cust_id = w.cust_id and e.event_id = w.event_id
CROSS APPLY (values(c.updated_On),(w.updated_on)) as t(updatedOn)
group by e.cust_id, e.event_id
customer_id | event_id | recent_timestamp |
---|---|---|
1 | 100 | 2020-02-01 00:00:00.000 |