简体   繁体   English

如何优化该T-SQL查询?

[英]How can this T-SQL query be optimized?

I'm relative new to sql and I would like some help with this one. 我是sql的新手,我希望对此有所帮助。 Basically, I'm trying to do some calculations in the query because functions were a bit slow. 基本上,我试图在查询中进行一些计算,因为函数有点慢。 Could you guys improve on this? 你们可以在这方面改善吗?

-- 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

Try this 尝试这个

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

Try this solution: 试试这个解决方案:

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;

You should check also if you have one of the following indices: CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc, al) or CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc) INCLUDE (al) . 您还应该检查是否具有以下索引之一: CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc, al)CREATE [UNIQUE] INDEX index_name ON dbo.ATT (DY, sc) INCLUDE (al)

You'll have to compare the results with your current query, but this is how I would probably accomplish this: 您必须将结果与当前查询进行比较,但这就是我可能会做到的方式:

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

Without having sample data to test with, I think this would be the easiest method to take. 如果没有可供测试的样本数据,我认为这将是最简单的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM