2012-11-21 101 views
3

我有以下查詢,這通常工作,並且應該返回覆蓋定義時間範圍的所有行(取最接近的現有和未來的行如果沒有絕對匹配 - 在http://www.orafaq.com/node/1834概述)引用在外部查詢子查詢

SELECT * FROM table 
    WHERE id=__ID__ AND `date` BETWEEN 
    IFNULL((SELECT MAX(`date`) FROM table WHERE id=__ID__ AND `date`<=__LOWERLIMIT__), 0) 
    AND 
    IFNULL((SELECT MIN(`date`) FROM table WHERE id=__ID__ AND `date`>=__UPPERLIMIT__), UNIX_TIMESTAMP()) 
ORDER BY `date` 

,但希望通過參考外部選擇,以減少這兩個表子查詢,但顯然它不喜歡它

SELECT * FROM (SELECT * FROM table WHERE id=__ID__) b 
    WHERE `date` BETWEEN 
    IFNULL((SELECT MAX(`date`) FROM b WHERE `date`<=__LOWERLIMIT__), 0) 
    AND 
    IFNULL((SELECT MIN(`date`) FROM b WHERE `date`>=__UPPERLIMIT__), UNIX_TIMESTAMP()) 
ORDER BY `date` 

有沒有辦法有三個無表中選擇查詢?

回答

3

你可以做這樣的事情有一個連接:

select * from table a 
    inner join (
     select id, 
       max(
        if(`date` <= __LOWERLIMIT__ ,`date`, 0) 
      ) as min_date,    
       min(
       if(`date` >= __UPPERLIMIT__ , `date`, UNIX_TIMESTAMP()) 
      ) as max_date 
      from table 
      where id = __ID__ 
      group by id 
    ) range on 
    range.id = a.id and 
    a.`date` between min_date and max_date; 

我不是MySQL的專家,所以如果需要道歉語法扭捏了一下。

更新:該OP還發現this very nice solution

+0

謝謝丹。我主要關心的是三種選擇的表現(表格會變得相當大,否則這不會是一個問題),但是現在的例子還涉及另外的聯合子選擇,並且沒有實際測量它,我會擔心的它可能有類似的潛在性能問題。您是否有特別的理由要在初始查詢中提出建議?感謝百萬 – user1841321

+0

@ user1841321,我相信如果你有一個給定的ID爲1000行,在你原來的最大和最小子查詢將重複1000次。有了這個連接解決方​​案,max和min的計算只會發生一次。 – dan1111

+0

因爲外部查詢,你相信它會被稱爲1000次嗎?它不會在這裏做同樣的事情(第二個選擇是連接的子選擇)?另外RANGE ON似乎不是特定於mysql的,它的目的是什麼? – user1841321

相關問題