0

我通常知道“涉及用户变量的表达式的求值顺序是未定义的”,所以我们不能在同一个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. 或者我可以编写两个单独的查询。但是这些并没有回答我的问题,即是否可以在查询和子查询中安全地定义和使用相同的变量。

4

1 回答 1

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无论如何,数据正在被多次读取和写入。

于 2015-05-27T23:05:40.707 回答