编写此SQL的更好方法

时间:2010-04-10 18:45:47

标签: sql sql-server-2005 refactoring

我有下表:

create table ARDebitDetail(ID_ARDebitDetail int identity, 
                  ID_Hearing int, ID_AdvancedRatePlan int)

我正在尝试根据ID_Hearing获取最新的ID_AdvancedRatePlan。最新的我的意思是最大的ID_ARDebitDetail。我有这个查询,它工作正常。

    select ID_AdvancedRatePlan
    from ARDebitDetails
    where ID_Hearing = 135878
    and ID_ARDebitDetail = 
            (   select max(ID_ARDebitDetail) 
                from ARDebitDetails 
                where ID_AdvancedRatePlan > 0 and ID_Hearing = 135878
            )

然而,它看起来很丑陋,闻起来很糟糕。有没有办法以更简洁的方式重写它?

3 个答案:

答案 0 :(得分:2)

SELECT TOP 1 ID_AdvancedRatePlan
FROM ARDebitDetails
WHERE ID_Hearing = 135878
AND ID_AdvancedRatePlan > 0
ORDER BY ID_ARDebitDetail DESC

答案 1 :(得分:2)

在RDBMS中,SQL文本中的代码气味很少,代码在您的模式中有异味。例证:在没有适当索引的表中搜索某些条件,这将始终导致表扫描。要获取给定ID_Hearing的最后一个ID_AdvancedRatePlan,请相应地组织表:

create clustered index cdxARDebitDetail 
on ARDebitDetail (ID_Hearing, ID_ARDebitDetail DESC);

如果不希望更改聚簇索引,则对于各种版本,应提供覆盖非聚簇索引。无论你做什么,它的要点是你不应该每次扫描表,这是部署灾难的秘诀。

然后你可以按照自己的意愿搜索,电气的回答是一个非常好的答案。

答案 2 :(得分:2)

使用公用表表达式的另一种解决方案是:

With RankedItems
    (
    Select ID_ARDebitDetail, ID_AdvancedRatePlan
        , ROW_NUMBER() OVER( ORDER BY ID_ARDebitDetail DESC) As ItemRank
    From ARDebitDetails 
    Where ID_AdvancedRatePlan > 0
        And ID_Hearing = 135878
    )
Select ID_AdvancedRatePlan
From RankedItems 
Where ItemRank = 1