MySQL 没有重复数据的最近日期
MySQL nearest date without duplicated data
所以我需要显示我所有的客户和相关的预订号(如果没有预订则为空),而不需要重复的客户。如果客户有很多预订,我只需要显示最近的预订日期。我不明白为什么我的查询不起作用。
这是做了什么:http://sqlfiddle.com/#!9/df0455/19
SELECT c.name, x.number, x.start_date
FROM customer c
LEFT JOIN
(SELECT b.customer_id, b.number, b.start_date
FROM booking b
INNER JOIN (
SELECT customer_id, MIN(ABS(TIME_TO_SEC(TIMEDIFF(NOW(), start_date)))) as mindiff
FROM booking
GROUP BY customer_id
) nearest ON b.customer_id = nearest.customer_id AND ABS(TIME_TO_SEC(TIMEDIFF(NOW(), start_date))) = mindiff
) AS x ON c.id = x.customer_id
其实Paul
显示了3次,只需要显示Paul
一次,最近的预订号是booking-1 2019-11-05 21:45:00
希望你能帮帮我
您可以使用行限制相关子查询进行过滤:
select c.name, b.number, b.start_date
from customer c
inner join booking b on b.customer_id = c.id
where b.start_date = (
select b1.start_date
from booking b1
where b1.customer_id = b.customer_id
order by abs(timestampdiff(second, now(), b1.start_date))
limit 1
)
在您的数据库中 Fiddle、this produces:
name number start_date
Paul booking-1 2019-11-05T21:45:00Z
John booking-3 2019-09-27T21:45:00Z
Morgan booking-5 2019-09-27T21:45:00Z
如果您还想显示没有预订的客户,那么您可以 left join
并将过滤移动到 join
:
的 on
子句
select c.name, b.number, b.start_date
from customer c
left join booking b
on b.customer_id = c.id
and b.start_date = (
select b1.start_date
from booking b1
where b1.customer_id = b.customer_id
order by abs(timestampdiff(second, now(), b1.start_date))
limit 1
)
您可以使用NOT EXISTS
获取最近的预订并加入客户:
SELECT c.id, c.name, t.number, t.start_date
FROM customer c
LEFT JOIN (
SELECT b.* FROM booking b
WHERE NOT EXISTS (
SELECT 1 FROM booking
WHERE customer_id = b.customer_id
AND ABS(TIMESTAMPDIFF(SECOND, NOW(), start_date)) < ABS(TIMESTAMPDIFF(SECOND, NOW(), b.start_date))
)
) t ON t.customer_id = c.id
参见demo。
结果:
| id | name | number | start_date |
| --- | ------ | --------- | ------------------- |
| 1 | Paul | booking-1 | 2019-11-05 21:45:00 |
| 2 | John | booking-3 | 2019-09-27 21:45:00 |
| 3 | Morgan | booking-5 | 2019-09-27 21:45:00 |
| 4 | Jane | | |
| 5 | Mike | | |
所以我需要显示我所有的客户和相关的预订号(如果没有预订则为空),而不需要重复的客户。如果客户有很多预订,我只需要显示最近的预订日期。我不明白为什么我的查询不起作用。
这是做了什么:http://sqlfiddle.com/#!9/df0455/19
SELECT c.name, x.number, x.start_date
FROM customer c
LEFT JOIN
(SELECT b.customer_id, b.number, b.start_date
FROM booking b
INNER JOIN (
SELECT customer_id, MIN(ABS(TIME_TO_SEC(TIMEDIFF(NOW(), start_date)))) as mindiff
FROM booking
GROUP BY customer_id
) nearest ON b.customer_id = nearest.customer_id AND ABS(TIME_TO_SEC(TIMEDIFF(NOW(), start_date))) = mindiff
) AS x ON c.id = x.customer_id
其实Paul
显示了3次,只需要显示Paul
一次,最近的预订号是booking-1 2019-11-05 21:45:00
希望你能帮帮我
您可以使用行限制相关子查询进行过滤:
select c.name, b.number, b.start_date
from customer c
inner join booking b on b.customer_id = c.id
where b.start_date = (
select b1.start_date
from booking b1
where b1.customer_id = b.customer_id
order by abs(timestampdiff(second, now(), b1.start_date))
limit 1
)
在您的数据库中 Fiddle、this produces:
name number start_date
Paul booking-1 2019-11-05T21:45:00Z
John booking-3 2019-09-27T21:45:00Z
Morgan booking-5 2019-09-27T21:45:00Z
如果您还想显示没有预订的客户,那么您可以 left join
并将过滤移动到 join
:
on
子句
select c.name, b.number, b.start_date
from customer c
left join booking b
on b.customer_id = c.id
and b.start_date = (
select b1.start_date
from booking b1
where b1.customer_id = b.customer_id
order by abs(timestampdiff(second, now(), b1.start_date))
limit 1
)
您可以使用NOT EXISTS
获取最近的预订并加入客户:
SELECT c.id, c.name, t.number, t.start_date
FROM customer c
LEFT JOIN (
SELECT b.* FROM booking b
WHERE NOT EXISTS (
SELECT 1 FROM booking
WHERE customer_id = b.customer_id
AND ABS(TIMESTAMPDIFF(SECOND, NOW(), start_date)) < ABS(TIMESTAMPDIFF(SECOND, NOW(), b.start_date))
)
) t ON t.customer_id = c.id
参见demo。
结果:
| id | name | number | start_date |
| --- | ------ | --------- | ------------------- |
| 1 | Paul | booking-1 | 2019-11-05 21:45:00 |
| 2 | John | booking-3 | 2019-09-27 21:45:00 |
| 3 | Morgan | booking-5 | 2019-09-27 21:45:00 |
| 4 | Jane | | |
| 5 | Mike | | |