我正在尝试使用while循环进行选择联合,从而获得错误

时间:2013-10-10 18:31:30

标签: sql sql-server

declare @year int
set @year = 2009

while(year <= 2020)
begin

  SELECT A.dsformfieldvalue                              as Instrumento ,
         AVG(DATEDIFF(day, B.DTSTARTDATE , C.DTENDDATE)) as TempoMedio  ,
         'Jul/2009 a Dez/2009'                           as Periodo
  from       wfflow_form_field_log A
  right join wfflow_execute_task   B on A.codflowexecute = B.codflowexecute
  right join wfflow_execute_task   C on B.codflowexecute = C.codflowexecute
  where A.codflow  in (326, 439)
    and A.codfield =  2498
    and B.codtask  =  7064
    and C.codtask  =  7095
    and CONVERT(CHAR(4), B.DTSTARTDATE, 120) = @year
    and CONVERT(CHAR(4), B.DTSTARTDATE, 100) in ('Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')

  set @year = @year + 1

  group by A.dsformfieldvalue

  union all

end

基本上我正在尝试做的是大幅减少重复代码的数量,因为我必须联合一大堆选择。我正在尝试使用while循环,但它无法正常工作。有什么输入吗?

2 个答案:

答案 0 :(得分:2)

我认为你要做的就是这个

select * 
from wfflow_form_field_log A
     right join wfflow_execute_task B on 
          A.codflowexecute = B.codflowexecute
where year(b.dtstartdate) between 2009 and 2020
and month(b.dtstartdate)>=7
and ... -- other filters

答案 1 :(得分:0)

您的SQL在语法上无效。 select1语句的一般形式是

select <result-columns>
from <from-clause-including-joins>
where <where-criteria>
group by <group-by-criteria>
having <having-criteria>
order by <order-by-criteria>

union / union all的一般形式是

<select-statement>
UNION [ALL]
<select-statement>
...

其中每个select语句返回相同数量的列,并且每个select语句中的相应列具有相同类型或可隐式转换为第一个select语句中列类型的类型。

您已发表声明

set @year = @year + 1

以便它是select语句的一部分。

此外,您添加了UNION ALL,后面没有select语句。

解决这些问题,你应该做得很好。但是......正如另一个答案所指出的那样,你真正要做的就是选择一系列年份。您不需要union:您只需要合适的分组。

如果是我的查询,我会做这样的事情(如果我正确理解你的意图):

declare @dtFrom datetime = '2009-01-01 00:00:00.000' -- start of period
declare @dtThru datetime = '2020-12-31 23:59:59.996' -- end of period

select year             = datepart(year,b.dtstartdate) ,
       period           = case datepart(month,b.dtstartdate) / 6 when 1 then 'Jan-Jun' else 'Jul-Dec' end ,
       instrumento      = a.dsformfieldvalue ,
       tempomento       = avg( datediff(day, b.dtstartdate , c.dtenddate ) )
from       wfflow_form_field_log a
right join wfflow_execute_task   b on A.codflowexecute = B.codflowexecute
                                  and B.codtask        =  7064
                                  and b.dtStartDate between @dtFrom and @dtThru
right join wfflow_execute_task   d on B.codflowexecute = C.codflowexecute
                                  and C.codtask        =  7095
where A.codflow  in (326, 439)
  and A.codfield =  2498
group by datepart(year,b.dtStartDate) ,
         case datepart(month,b.dtstartdate) / 6 when 1 then 'Jan-Jun' else 'Jul-Dec' end ,
         A.dsformfieldvalue
order by 1,2,3 -- order by the first 3 columns (the grouping columns)

容易!