如何优化此T-SQL查询?

时间:2013-05-31 14:44:05

标签: sql sql-server tsql

我对sql相对较新,我希望得到一些帮助。基本上,我正在尝试在查询中进行一些计算,因为函数有点慢。你们可以改进吗?

-- Query to retrive ADA from every school
Select  Distinct DY, 
        DATENAME(MM,DT) as 'Month',
        CONVERT(nvarchar,DT,101) as 'Date',
        (
            Select ((@M_stu - (Select Count(SC) from dbo.ATT where sc=1 AND al!='' AND DY=T.DY))/@M_stu)*100
        ) as 'Merced ADA',
        (
            Select ((@A_stu - (Select Count(SC) from dbo.ATT where sc=2 AND al!='' AND DY=T.DY))/@A_stu)*100
        ) as 'Atwater ADA',
        (
            Select ((@L_stu - (Select Count(SC) from dbo.ATT where sc=3 AND al!='' AND DY=T.DY))/@L_stu)*100
        ) as 'Livingston ADA',
        (
            Select ((@B_stu - (Select Count(SC) from dbo.ATT where sc=4 AND al!='' AND DY=T.DY))/@B_stu)*100
        ) as 'Buhach ADA',
        (
            Select ((@Y_stu - (Select Count(SC) from dbo.ATT where sc=5 AND al!='' AND DY=T.DY))/@Y_stu)*100
        ) as 'Yosemite ADA',
        (
            Select ((@I_stu - (Select Count(SC) from dbo.ATT where sc=6 AND al!='' AND DY=T.DY))/@I_stu)*100
        ) as 'Independence ADA',
        (
            Select ((@G_stu - (Select Count(SC) from dbo.ATT where sc=10 AND al!='' AND DY=T.DY))/@G_stu)*100
        ) as 'Golden Valley ADA',
        (
            Select ((@S_stu - (Select Count(SC) from dbo.ATT where sc=92 AND al!='' AND DY=T.DY))/@S_stu)*100
        ) as 'Sequoia ADA'
From dbo.ATT as T
Order by DY ASC

3 个答案:

答案 0 :(得分:3)

试试这个

Select  DY, 
        DATENAME(MM,DT) as 'Month',
        CONVERT(nvarchar,DT,101) as 'Date',
        @M_stu - (Count(case when sc=1 AND al!='' AND DY=T.DY then 1 else null end)/@M_stu)*100 as 'Merced ADA',
        @A_stu - (Count(case when sc=2 AND al!='' AND DY=T.DY then 1 else null end)/@A_stu)*100 as 'Atwater ADA',
        ...
From dbo.ATT as T
GROUP BY DY, DT
Order by DY ASC

答案 1 :(得分:3)

试试这个解决方案:

SELECT  DISTINCT 
        t.DY                            AS DY, 
        DATENAME(MM,t.DT)               AS [Month],
        CONVERT(NVARCHAR,t.DT,101)      AS [Date],
        ((@M_stu - d.[1])/@M_stu)*100   AS [Merced ADA],
        ((@A_stu - d.[2])/@A_stu)*100   AS [Atwater ADA],
        ((@L_stu - d.[3])/@L_stu)*100   AS [Livingston ADA],
        ((@B_stu - d.[4])/@B_stu)*100   AS [Buhach ADA],
        ((@Y_stu - d.[5])/@Y_stu)*100   AS [Yosemite ADA],
        ((@I_stu - d.[6])/@I_stu)*100   AS [Independence ADA],
        ((@G_stu - d.[10])/@G_stu)*100  AS [Golden Valley ADA],
        ((@S_stu - d.[92])/@S_stu)*100  AS [Sequoia ADA]
FROM    dbo.ATT AS t
OUTER APPLY (
    SELECT  c.*
    FROM (
        SELECT  a.sc
        FROM    dbo.ATT AS a
        WHERE   a.sc IN (1,2,3,4,5,6,10,92) 
        AND     a.al!='' 
        AND     a.DY=t.DY
    ) b
    PIVOT( COUNT(b.sc) FOR a.sc IN ([1],[2],[3],[4],[5],[6],[10],[92]) ) c
) d
ORDER BY t.DY ASC;

如果您使用以下索引之一,还应检查:CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc, al)CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc) INCLUDE (al)

答案 2 :(得分:1)

您必须将结果与当前查询进行比较,但这是我可能实现的目标:

Select  Distinct DY, 
        DATENAME(MM,DT) as Month,
        CONVERT(char(10),DT,101) as Date,
        @M_stu - sum(case when sc=1 then 1.0 else 0.0 end)/@M_stu)*100 as [Merced ADA],
        @A_stu - sum(case when sc=2 then 1.0 else 0.0 end)/@A_stu)*100 as [Atwater ADA],
        @L_stu - sum(case when sc=3 then 1.0 else 0.0 end)/@L_stu)*100 as [Livingston ADA],
        @B_stu - sum(case when sc=4 then 1.0 else 0.0 end)/@B_stu)*100 as [Buhach ADA],
        @Y_stu - sum(case when sc=5 then 1.0 else 0.0 end)/@Y_stu)*100 as [Yosemite ADA],
        @I_stu - sum(case when sc=6 then 1.0 else 0.0 end)/@I_stu)*100 as [Independence ADA],
        @G_stu - sum(case when sc=10 then 1.0 else 0.0 end)/@G_stu)*100 as [Golden Valley ADA],
        @S_stu - sum(case when sc=92 then 1.0 else 0.0 end)/@S_stu)*100 as [Sequoia ADA]
From    dbo.ATT as T
Where   al!=''
Order by DY ASC

如果没有要测试的样本数据,我认为这是最简单的方法。