【问题标题】:MySQL nearest date without duplicated data没有重复数据的 MySQL 最近日期
【发布时间】:2020-09-22 05:35:55
【问题描述】:

所以我需要显示我的所有客户以及相关的预订号(如果没有预订,则为空),而不会出现重复的客户。如果客户有很多预订,我只需要显示最近的预订日期。我不明白为什么我的查询不起作用。

这是做什么的: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

希望你能帮到我

【问题讨论】:

    标签: mysql sql date join greatest-n-per-group


    【解决方案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   |           |                     |
    

    【讨论】:

      【解决方案2】:

      您可以使用限制行的相关子查询进行过滤:

      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
      )
      

      在您的 DB 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 并将过滤器移至joinon 子句:

      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
          )
      

      【讨论】:

      • 感谢您的回答,它工作得非常好,只是一个人认为我需要它来显示客户,即使他没有与预订相关联。我想只显示名称然后为 null 进行预订,我在您的查询中尝试了左连接,但它对您不起作用,您知道为什么吗?
      • @John:您需要将 where 子句移动到连接条件。请参阅我的更新答案。
      猜你喜欢
      • 2012-09-27
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 2014-09-02
      相关资源
      最近更新 更多