如何重写UNION sql查询,使其以SELECT开头

时间:2016-04-15 18:03:08

标签: mysql sql

我有一个恼人的问题,我需要在没有UNION

的情况下编写这个sql
(SELECT entry_id, url_title, channel_id, entry_date, title 
 FROM exp_channel_titles 
 WHERE exp_channel_titles.channel_id = 5 
   AND status = 'open' 
 ORDER BY entry_date asc 
 LIMIT 2)
UNION
(SELECT entry_id, url_title, channel_id, entry_date, title 
 FROM exp_channel_titles 
 WHERE exp_channel_titles.channel_id = 6 
   AND status = 'open'
   AND entry_date > ((unix_timestamp(Now()))+(2*86400))
 ORDER BY entry_date asc LIMIT 1)
UNION
    (SELECT entry_id, url_title, channel_id, entry_date, title
    FROM exp_channel_titles
    WHERE exp_channel_titles.channel_id = 5
    AND status = 'open'
    ORDER BY entry_date asc LIMIT 1,2)
    LIMIT 3;

所以它的作用是选择2个新闻故事,然后选择未来“故事”中的事件,如果没有事件故事添加另一个新闻故事。

所以有两个类别,但其中一个有不同的选择,所以加权总是有3个,但如果可能的话就是一个事件。

我需要考虑使用连接执行此操作的方法,或者在没有()括号的情况下启动,以使其更简单。我加载的地方不喜欢UNION。

2 个答案:

答案 0 :(得分:1)

这是正确的语法:

select * from (SELECT entry_id, url_title, channel_id, entry_date, title, 1 as comesFrom 
 FROM exp_channel_titles 
 WHERE exp_channel_titles.channel_id = 5 
   AND status = 'open' 
 ORDER BY entry_date asc 
 LIMIT 2) AS part1
UNION
select * from (SELECT entry_id, url_title, channel_id, entry_date, title, 2 as comesFrom
 FROM exp_channel_titles 
 WHERE exp_channel_titles.channel_id = 6 
   AND status = 'open'
   AND entry_date > ((unix_timestamp(Now()))+(2*86400))
 ORDER BY entry_date asc LIMIT 1) as part2
UNION
select * from  (SELECT entry_id, url_title, channel_id, entry_date, title, 3 as comesFrom
    FROM exp_channel_titles
    WHERE exp_channel_titles.channel_id = 5
    AND status = 'open'
    ORDER BY entry_date asc LIMIT 1,2) as part3
-- may be you want an order by here also
LIMIT 3;

我还添加了一个comeFrom字段作为标志,以便在最终记录集中知道特定记录的来源。在某些情况下它很有用。

答案 1 :(得分:0)

最后的答案需要为每个子查询添加额外的SELECT和AS别名

SELECT * FROM ( 
    SELECT * FROM (SELECT entry_id, url_title, channel_id, entry_date, title
        FROM exp_channel_titles
        WHERE channel_id = 5
        AND status = 'open'
        ORDER BY entry_date asc LIMIT 2) 
    AS news
UNION
    SELECT * FROM (SELECT entry_id, url_title, channel_id, entry_date, title
        FROM exp_channel_titles
        WHERE channel_id = 6
        AND status = 'open'
        AND entry_date > ((unix_timestamp(Now()))+(2*86400))
        ORDER BY entry_date asc LIMIT 1) 
    AS gallery
UNION 
    SELECT * FROM (SELECT entry_id, url_title, channel_id, entry_date, title
        FROM exp_channel_titles
        WHERE channel_id = 5
        AND status = 'open'
        ORDER BY entry_date asc LIMIT 1,2) 
    AS more_news
) AS articles LIMIT 3;

当你使用SELECT *换行时,它似乎是MySQL,它现在需要以不同的方式连接它们,所以每个()现在需要SELECT * FROM()AS别名,这有点矫枉过正,但是有意义,因为它想要让所有cols可用。

我仍然想要一个更轻松的解决方案,因为这是很多步骤,但它有效,对我很好。