【问题标题】:Mysql select from inner select with joinMysql从内部选择中选择并加入
【发布时间】:2014-05-18 22:26:30
【问题描述】:

我可以这样做吗?基本上,我用户内部选择来选择大于NOW() 的最低日期,例如 9.4.2014 会为每个事件 ID 计算这个。现在我想返回这个,这是代码:

SELECT id_event , event_title, event_details, dates.event_date, id_show, id_category,  distance FROM(
SELECT event.id_event id_event, event_title, event_details, min(event_date_time) event_date_time, event_showtime.id_show , event_category.id_category id_category, ( 6371 * ACOS( COS( RADIANS(  '49.20513921227407' ) ) * COS( RADIANS( event_showtime.latitude ) ) * COS( RADIANS( event_showtime.longitude ) - RADIANS(  '18.762441839599678' ) ) + SIN( RADIANS(  '49.20513921227407' ) ) * SIN( RADIANS( event_showtime.latitude ) ) ) ) AS distance
FROM event
JOIN event_showtime ON event.id_event = event_showtime.id_event
JOIN event_category ON event.id_category = event_category.id_category
JOIN (  SELECT id_event, min(event_date_time) as event_date_time FROM event_showtime
WHERE event_date_time > NOW()
GROUP BY id_event ) AS dates ON event.id_event = dates.id_event
 WHERE event_date_time > NOW()
GROUP BY event.id_event
HAVING distance <  '5'
ORDER BY distance
LIMIT 0 , 20
  )t

这是带有 3 个表的 SQLfiddle http://www.sqlfiddle.com/#!2/6545ab/51 :)

如何访问顶部选择中的那些内部细节?

【问题讨论】:

    标签: mysql sql datetime select


    【解决方案1】:

    如果有多个具有相同名称的列,您需要为列提供表别名

       SELECT 
    es.id_show,
    e.id_event , 
    e.event_title, 
    e.event_details, 
    d.event_date_time,
    ec.id_category, 
     ( 6371 * ACOS( COS( RADIANS(  '49.20513921227407' ) ) * COS( RADIANS( es.latitude ) ) * COS( RADIANS( es.longitude ) - RADIANS(  '18.762441839599678' ) ) + SIN( RADIANS(  '49.20513921227407' ) ) * SIN( RADIANS( es.latitude ) ) ) ) AS distance  
    FROM event e
    JOIN event_showtime es ON e.id_event = es.id_event
    JOIN event_category ec ON e.id_category = ec.id_category
    JOIN (  SELECT id_event, 
          min(event_date_time) as event_date_time 
          FROM event_showtime
    WHERE event_date_time > NOW()
    GROUP BY id_event ) AS d 
      ON (es.id_event = d.id_event AND es.event_date_time =d.event_date_time)
     WHERE d.event_date_time > NOW()
    GROUP BY e.id_event
    -- HAVING distance <  '5'
    ORDER BY distance
    LIMIT 0 , 20
    

    这是您使用HAVING 子句检查距离应小于 5 的查询的简化版本,但对于第二个事件,距离是 112.773868864733 在我的查询中我已经评论了有子句只是为了显示您的结果,第二件事是您要求最接近 NOW() 的日期,但不包括过去的日期,因此在您提供的 event_showtime 示例数据集中

    `id_show`, `id_event`, `latitude`, `longitude`, `event_date_time`
    (1, 1, 49.2016762922894, 18.7615620750428, '2014-03-31 16:13:17'),
    (2, 1, 49.2016762922894, 18.7615620750428, '2014-04-01 20:00:00'),
    (3, 2, 49.2113914818564, 18.7520992416382, '2014-03-31 15:00:00'),
    (4, 2, 49.0545135142313, 20.2952223676682, '2014-04-16 11:00:00'),
    (5, 2, 49.2113914818564, 18.7520992416382, '2014-04-23 11:00:00'),
    (6, 2, 49.0545135142313, 20.2952223676682, '2014-04-30 11:00:00'),
    (7, 2, 49.2016762922894, 18.7615620750428, '2014-04-29 12:00:00'),
    (8, 1, 49.2016762922894, 18.7615620750428, '2014-04-24 12:00:00');
    

    对于事件 id 1 有 3 个日期时间 2014-03-31 16:13:17 ,2014-04-01 20:00:00,2014-04-24 12:00:00 日期 2014-04-24 12:00:00 是事件 id 2 的最近一个日期 2014-04-16 11:00:00 是最近的一个而不是第 23 个日期,您在 cmets 中询问的第三件事 id_show这是错误的,您从子查询中的最后一次连接需要另一个带有event_date_time 的条件才能获得您需要的确切 ID

    希望有意义

    Fiddle Demo

    根据您的具体要求,您可以选择距离限制最近的日期

    SELECT t.* FROM (
    SELECT 
      es.id_show,
      e.id_event,
      e.event_title,
      e.event_details,
      MIN(es.event_date_time) event_date_time,
      ec.id_category,
      es.distance 
    FROM
      event e 
      JOIN event_category ec 
        ON e.id_category = ec.id_category 
      JOIN 
        (SELECT 
          `id_show`,
          `id_event`,
          `latitude`,
          `longitude`,
          event_date_time,
          (
            6371 * ACOS(
              COS(RADIANS('49.20513921227407')) * COS(RADIANS(event_showtime.latitude)) * COS(
                RADIANS(event_showtime.longitude) - RADIANS('18.762441839599678')
              ) + SIN(RADIANS('49.20513921227407')) * SIN(RADIANS(event_showtime.latitude))
            )
          ) AS distance 
        FROM
          event_showtime 
        WHERE `event_date_time` > NOW() 
        HAVING distance < 5) es 
        ON (e.id_event = es.id_event) 
        GROUP BY e.id_event
       ) t
       JOIN `event_showtime` es USING(id_event,event_date_time)
    ORDER BY t.distance 
    LIMIT 0, 20 
    

    Fiddle Demo

    【讨论】:

    • 很好,但是在我提供的小提琴上尝试了这个,你也发布了,id_show 与 datetime 不匹配,请查看插入语句:) 但它给了我一个新的看 :) 我已经修复了一点 sqlfiddle.com/#!2/6545ab/106 但我仍然缺少一些东西:/ 位置不好
    • 该查询的 ID 事件 = 2 应该返回日期 = 23.4 和 id_show = 5:P 你能指点我的方向吗?错误可能在哪里?
    • @XOOLOOO 看到我更新的答案希望它能清除所有最近的日期场景和 id_show
    • 非常感谢您:P 但请再次阅读我的最后一条评论,您查询的第二行应返回 id_show = 5,日期为 23,因为距离为 5 公里。在查询中,我正在寻找纬度为 49.20513921227407 和经度为 18.762441839599678 的位置,因此它无法返回 120 公里的距离值。它必须是 id_show=5 的行,因为它距离较远并且具有 > NOW() 的最低日期。是的,你是对的2014-04-16 11:00:00,因为第二个会起作用,但我需要这个包括距离条件,这很重要。更多在第二条评论
    • 先生你是神! :) 我认为这项工作,必须在真实数据库中进行一些测试 :) 非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多