SELECT t.*,t2.* ,t3.*,t3.[Wwater] as wwt,t3.[Nwater] as nwt 
    ,isnull((select top 1 cast(nwater as varchar)+'/'+cast(wwater as varchar)  from [PYPDA].[dbo].[ZM_STA_HIS] t4
                    where t4.dtime>GETDATE()-1 and datediff(mi,t4.[dTime],t2.[dTime])>15 and t2.zmid=t4.zmid order by t4.[dTime] desc)
                    ,-9999) Watera
 
                  FROM [PYPDA].[dbo].[stu207_was_b] t
                 ,[PYPDA].[dbo].[ZM_STA] t2 ,[PYPDA].[dbo].[ZM_Watering] t3
                 where t.stcd=t2.zmid and t2.zmid=t3.zmid and t.starea like '%{0}%'
                 order by t2.lev,t.stpqt.*,t2.* ,t3.*不用优化先,主要是怎么把 isnull((select top 1 cast(nwater as varchar)+'/'+cast(wwater as varchar)  from [PYPDA].[dbo].[ZM_STA_HIS] t4
                    where t4.dtime>GETDATE()-1 and datediff(mi,t4.[dTime],t2.[dTime])>15 and t2.zmid=t4.zmid order by t4.[dTime] desc)
                    ,-9999) Watera
提出来吧

解决方案 »

  1.   

    datediff(mi,t4.[dTime],t2.[dTime])>15可以改成t2.[dTime]>dateadd(mi,15,t4.[dTime])
      

  2.   

    用sql查询分析器的 显示估计执行计划
      

  3.   

    显示估计执行计划执行后,索引假脱机占65% ,扫描表stu207_was_b34占 %
      

  4.   

    没法测试,楼主自己测吧SELECT 
           t.*
           ,t2.* 
           ,t3.*
           ,t3.[Wwater] as wwt
           ,t3.[Nwater] as nwt  
           ,isnull(cast(t4.nwater as varchar)+'/'+cast(t4.wwater as varchar),-9999) Watera
           ,row_number() over(order by isnull(t4.[dTime],GETDATE()) desc) num_id
      FROM [PYPDA].[dbo].[stu207_was_b] t
     inner join [PYPDA].[dbo].[ZM_STA] t2
        on t.stcd=t2.zmid
     inner join [PYPDA].[dbo].[ZM_Watering] t3
        on t2.zmid=t3.zmid
      left join [PYPDA].[dbo].[ZM_STA_HIS] t4
        on t4.dtime>GETDATE()-1 
       and datediff(mi,t4.[dTime],t2.[dTime])>15 
       and t2.zmid=t4.zmid
     where t.starea like '%{0}%'
       and num_id=1
     order by t2.lev,t.stpq
    ;
      

  5.   

    测试我来吧,因为环境问题。and num_id=1 测试通不过
      

  6.   

    执行条件:SQLSERVER2005以上,算是高效的方法了。还有一种使用自定义函数的方法,是否会更快,没有测试环境不能断言。
    --这里返回的内容,会多个排序列SNO
    SELECT * FROM          
    (SELECT t.*,
           t2.*,
           t3.*,
           t3. Wwater as wwt,
           t3. Nwater as nwt,
           CASE WHEN t4.dtime > GETDATE() - 1
                     and datediff(mi, t4.dTime, t2.dTime) > 15 THEN cast(nwater as varchar) + '/' + cast(wwater as varchar)
                ELSE  -9999 Watera,
           row_number() over(PARTITION BY t4.zmid ORDER BY t4.dTime desc) SNO
      FROM PYPDA.dbo.stu207_was_b t,
           PYPDA.dbo.ZM_STA t2 LEFT JOIN PYPDA.dbo.ZM_STA_HIS t4 ON t2.zmid = t4.zmid
           PYPDA.dbo.ZM_Watering t3       
     where t.stcd = t2.zmid
       and t2.zmid = t3.zmid
       and t.starea like '%{0}%'
     order by t2.lev,
              t.stpq          
              t.*,
              t2.*,
              t3.* )A
    WHERE SNO = 1
      

  7.   

    晕死,CASE语法忘记加END结束了,你自己添加下。
    CASE WHEN ..... THEN ... ELSE ... END
      

  8.   

    另外5楼的SQL错误多处,排除语法错误后,执行的结果还是错误的,请勿效仿。
      

  9.   

    运行不通过,提示 order by t2.lev,
              t.stpq ,         
              t.lttd ,
              t2.dtime,
              t3.dt )A   中A 不正确
      

  10.   

    建议你把order by t2.lev,
              t.stpq          
              t.*,
              t2.*,
              t3.* 
    删除,如果必须排序,放在最外层不能放在子查询中,完整的错误提示是:
    “除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效。”
      

  11.   

    另外请注意,这里使用了子查询,子查询有一个需要非常注意的地方,那就是列名不能重复,否则就会报错,你的这种写法将导致列名重复。
    修改方法是,在一开始的SELECT t.*,t2.* ,t3.*,处,不要用*,确保每个列名列出,发现同列名只保留一个或者使用别名。