mySQL加入或子查询

时间:2011-07-10 02:23:11

标签: mysql select join

我有三张桌子:表演,插曲和播出。每个节目都有多集,每集都有多次播出。我希望每个节目都有一行airing.start_time最接近start_time到现在(但将来)。如果没有未来start_time,那么无论如何我都想要该行(start_time应为空)。

这是我当前的查询:

    SELECT s.project_id,
           s.title, 
           s.description, 
           s.topic, 
           s.status, 
           a.start_time, 
           a.channel 
      FROM show s 
 LEFT JOIN episode e ON s.project_id = e.project_id 
 LEFT JOIN airing a ON e.episode_id = a.episode_id 
     WHERE s.status = "Active" AND s.title LIKE "a%" AND a.start_time > NOW()
  ORDER BY s.title ASC, a.start_time ASC
  GROUP BY s.project_id

我不确定下一步该去哪儿。有什么帮助吗?

4 个答案:

答案 0 :(得分:2)

不显示airing.channel

    SELECT s.project_id,
           s.title, 
           s.description, 
           s.topic, 
           s.status, 
           MIN(a.start_time) 
      FROM show s 
 LEFT JOIN episode e ON s.project_id = e.project_id 
 LEFT JOIN airing a ON e.episode_id = a.episode_id 
                    AND a.start_time > NOW()
     WHERE s.status = "Active" AND s.title LIKE "a%"
  GROUP BY s.project_id
  ORDER BY s.title ASC

也显示channel

    SELECT s.project_id,
           s.title, 
           s.description, 
           s.topic, 
           s.status, 
             ( SELECT a.start_time
                 FROM airing AS a 
                 JOIN episode AS e ON e.episode_id = a.episode_id 
                WHERE s.project_id = e.project_id 
                  AND a.start_time > NOW() 
             ORDER BY a.start_time
                LIMIT 1    
             )
           AS start_time,
             ( SELECT a.channel
                 FROM airing AS a 
                 JOIN episode AS e ON e.episode_id = a.episode_id 
                WHERE s.project_id = e.project_id 
                  AND a.start_time > NOW() 
             ORDER BY a.start_time
                LIMIT 1    
             )
           AS channel
      FROM show s     
     WHERE s.status = "Active" AND s.title LIKE "a%"
  ORDER BY s.title ASC

或:

    SELECT s.project_id,
           s.title, 
           s.description, 
           s.topic, 
           s.status, 
           a.start_time,
           a.channel   
      FROM show s     
 LEFT JOIN airing a ON a.airing_id =
                     ( SELECT a.airing_id
                         FROM airing AS a 
                         JOIN episode AS e ON e.episode_id = a.episode_id 
                        WHERE s.project_id = e.project_id 
                          AND a.start_time > NOW() 
                     ORDER BY a.start_time
                        LIMIT 1    
                     )   
     WHERE s.status = "Active" AND s.title LIKE "a%"
  ORDER BY s.title ASC

如果它们很慢,请告诉我们您在表格上有哪些索引以及这些字段的类型。

答案 1 :(得分:1)

要处理将来的开始时间,请将时间检查更改为

... AND ((a.start_time > NOW()) or (a.start_time is null))

假设你提到的“空”是空的。但是,如果您没有清除先前剧集的start_times,那么这将无效,您应该完全删除start_time检查。检查past_start时间是没有意义的,因为你正在做(x> y或x< y),只有在(x = y)时才会失败。

答案 2 :(得分:1)

此查询听起来像您想要的,但如果没有未来start_time

,频道也将为空
SELECT s.project_id,
       s.title, 
       s.description, 
       s.topic, 
       s.status, 
       a.start_time, 
       a.channel 
FROM show s 
LEFT JOIN episode e ON s.project_id = e.project_id 
LEFT JOIN (SELECT start_time, channel, episode_id FROM airing a1
           WHERE a1.start_time = (SELECT MIN(a2.start_time) FROM airing a2
                                  WHERE a2.start_time > NOW() AND
                                        a2.airing_id = a1.airing_id)
          ) a ON e.episode_id = a.episode_id 
WHERE s.status = 'Active' AND s.title LIKE 'a%'
ORDER BY s.title ASC, a.start_time ASC
GROUP BY s.project_id

根据ypercube的评论进行编辑:

SELECT s.project_id,
       s.title, 
       s.description, 
       s.topic, 
       s.status, 
       a.start_time, 
       a.channel 
FROM show s 
LEFT JOIN (SELECT a1.start_time, a1.channel, e.project_id
           FROM airing a1
                JOIN episode e ON a1.episode_id = e.episode_id
           WHERE a1.start_time = (SELECT MIN(a2.start_time) FROM airing a2
                                  WHERE a2.start_time > NOW() AND
                                        a2.airing_id = a1.airing_id)
          ) a ON s.project_id = a.project_id 
WHERE s.status = 'Active' AND s.title LIKE 'a%'
ORDER BY s.title ASC, a.start_time ASC
GROUP BY s.project_id

答案 3 :(得分:0)

试试这个:

SELECT s.project_id,
       s.title, 
       s.description, 
       s.topic, 
       s.status, 
       a.start_time, 
       a.channel 
FROM show s 
LEFT JOIN episode e ON s.project_id = e.project_id 
LEFT JOIN airing a ON e.episode_id = a.episode_id 
WHERE s.status = "Active" AND s.title LIKE "a%" AND a.start_time > NOW()
-- Here's the new bit:
AND a.start_time = (SELECT start_time from airing where episode_id = e.episode_id order by abs(now() - start_time) limit 1)
ORDER BY s.title ASC, a.start_time ASC
GROUP BY s.project_id

通过从现在的限制1开始按时间距离进行子选择(选择最差的一个),选择最接近“现在”的播出