2015-05-27 34 views
0

我通常知道"the order of evaluation for expressions involving user variables is undefined",所以我们不能在同一个select语句中安全地定义和使用变量。但是如果有子查询呢?举个例子,我有这样的事情:定义和使用一个变量与子查询?

select col1, 
     (select min(date_)from t where i.col1=col1) as first_date, 
     datediff(date_, (select min(date_)from t where i.col1=col1) 
       ) as days_since_first_date, 
     count(*) cnt 
from t i 
where anothercol in ('long','list','of','values') 
group by col1,days_since_first_date; 

有没有办法使用(select @foo:=min(date_)from t where i.col1=col1)安全,而不是重复的子查询?如果是这样,我可以在datediff函数中或第一次出现子查询(或任一个)吗?


当然,我可以做

select col1, 
     (select min(date_)from t where i.col1=col1) as first_date, 
     date_, 
     count(*) cnt 
from t i 
where anothercol in ('long','list','of','values') 
group by col1,date_; 

,然后做一些简单的后期处理,以获得datediff。或者我可以写两个单独的查询。但是这些不能回答我的问题,即是否可以在查询和子查询中安全地定义和使用相同的变量。

+1

此链接可能对您有所帮助。 http://stackoverflow.com/questions/16715504/mysql-define-a-variable-within-select-and-use-it-within-the-same-select –

回答

1

首先,您的查询没有意义,因为date_没有聚合函数。你会得到一个任意值。

这就是说,你可能重复子查询,但我不明白为什么这将是必要的。只需使用子查询:

select t.col1, t.first_date, 
     datediff(date_, first_date), 
     count(*) 
from (select t.*, (select min(date_) from t where i.col1 = t.col1) as first_date 
     from t 
     where anothercol in ('long','list', 'of', 'values') 
    ) t 
group by col1, days_since_first_date; 

正如我所提到的,尽管如此,第三列的值是有问题的。

注意:这对于实现子查询会产生额外开销。但是,无论如何,还是有一个group by,所以数据正在被多次读取和写入。

+0

重新分组和聚集,记我在'days_since_first_date'上进行了分组,这是每个'col1'与'date_'的一对一对应关系,也是'col1'上的。所以分组应该没问题。 – JQKP

+0

我不明白这是如何回答这个问题的,这是在子查询和查询中定义和使用相同变量是否安全。 – JQKP