如何改进下面的SQL查询?

时间:2012-02-07 03:39:22

标签: sql-server sql-server-2005

请查看以下查询

select 
    DATEADD(wk, DATEDIFF(wk, 6, creation_ts), 6) creation_ts 
    ,sum(case when (priority = 'P1') then 1 else 0 end) as P1 
    ,sum(case when (priority = 'P2') then 1 else 0 end) as P2 
    ,sum(case when (priority = 'P3') then 1 else 0 end) as P3 
    ,sum(case when (priority = 'P4') then 1 else 0 end) as P4 
    ,sum(case when (priority = 'P5') then 1 else 0 end) as P5
    ,count(*) Total
from dbo.BugzillaTrans

where 
    (cf_projectnumber = @Project_Number or @Project_Number is null) 
and (product_id = @product_id or @product_id is null) 
and (component_id = @component_id or @component_id is null) 
and (creation_ts >= @Start_Dt or @Start_Dt is null) 
and (creation_ts <= @End_Dt or @End_Dt is null) 
and priority in ('P1','P2','P3','P4','P5') 
and assigned_to in (select EmailAddress from dbo.users where role_id = @role_id or @role_id is null) 
and assigned_to in (select EmailAddress from dbo.users where team_id = @team_id or @team_id is null)
and assigned_to in (select EmailAddress from dbo.users where location_id = @location_id or @location_id is null) 
 group by DATEADD(wk, DATEDIFF(wk, 6, creation_ts), 6)

可以看出,在where子句中我使用SELECT子句从users表中获取记录。

and assigned_to in (select EmailAddress from dbo.users where role_id = @role_id or @role_id is null) 
and assigned_to in (select EmailAddress from dbo.users where team_id = @team_id or @team_id is null)
and assigned_to in (select EmailAddress from dbo.users where location_id = @location_id or @location_id is null) 

如何避免这种情况并以不同的方式写作?

或者有没有更好的方法(显然我确定,会有)编写整个程序?

由于

2 个答案:

答案 0 :(得分:1)

and assigned_to in (select EmailAddress from dbo.users where role_id = @role_id or @role_id is null)  
and assigned_to in (select EmailAddress from dbo.users where team_id = @team_id or @team_id is null) 
and assigned_to in (select EmailAddress from dbo.users where location_id = @location_id

可以改写为:

and assigned_to in
  ( select EmailAddress from dbo.users where ( role_id = @role_id or @role_id is null ) and
    ( team_id = @team_id or @team_id is null ) and ( location_id = @location_id ) )

答案 1 :(得分:1)

(正如你所指出的那样)可能有一百万种方法可以整体重写这个查询,但你提出的关于避免子选择的具体问题可以用inner join来回答。

SELECT 
    DATEADD(wk, DATEDIFF(wk, 6, bt.creation_ts), 6) AS creation_ts 
    ,SUM(CASE WHEN (bt.priority = 'P1') THEN 1 ELSE 0 END) AS P1 
    ,SUM(CASE WHEN (bt.priority = 'P2') THEN 1 ELSE 0 END) AS P2 
    ,SUM(CASE WHEN (bt.priority = 'P3') THEN 1 ELSE 0 END) AS P3 
    ,SUM(CASE WHEN (bt.priority = 'P4') THEN 1 ELSE 0 END) AS P4 
    ,SUM(CASE WHEN (bt.priority = 'P5') THEN 1 ELSE 0 END) AS P5
    ,COUNT(*) Total
FROM dbo.BugzillaTrans bt 
JOIN dbo.users u
    ON  bt.assigned_to = u.EmailAddress
WHERE   (bt.cf_projectnumber = @Project_Number OR @Project_Number IS NULL)
AND     (bt.product_id = @Product_ID OR @Product_ID IS NULL)
AND     (bt.component_id = @Component_ID OR @Component_ID IS NULL)
AND     (bt.creation_ts >= @Start_DT OR @Start_DT IS NULL)
AND     (bt.creation_ts <= @End_DT OR @End_DT IS NULL)
AND     (bt.priority IN ('P1', 'P2', 'P3', 'P4', 'P5'))
AND     (u.role_id = @Role_ID OR @Role_ID IS NULL)
AND     (u.team_id = @Team_ID OR @Team_ID IS NULL)
AND     (u.location_id = @Location_ID OR @Location_ID IS NULL)
GROUP BY
        DATEADD(WEEK, DATEDIFF(WEEK, 6, bt.creation_ts), 6)