2012-11-21 105 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

相关问题