SQL:如何根据同一列上的不同条件选择前1行

时间:2017-05-16 07:34:43

标签: sql sql-server tsql sql-server-2012

假设我有一个名为ItemCode的列的表,它具有固定格式xxx-xxxx,其中x是[0-9],例如ItemCode的可能值是097-1234

现在我想选择以ItemCode开头的最大987ItemCode的最后一个123,所以我想尝试做类似的事情(这个是错的)

SELECT TOP 1 ItemCode From Table 
WHERE ItemCode like '987%' OR ItemCode like '123%'
ORDER BY 1 DESC

那么如何编写一个可以选择每个条件的最后ItemCode的SQL?是否有任何通用方法可以扩展到选择N这些标准上的前M行?

(假设存在数据符合条件,此处应返回2行:最大ItemCode987开头,最大ItemCode123开头)

4 个答案:

答案 0 :(得分:2)

没有UNION的另一个选项,您可以使用此TOP 1 WITH TIESROW_NUMBER() OVER()

SELECT TOP 1 WITH TIES * 
From YourTable 
WHERE ItemCode like '987%' OR ItemCode like '123%'
ORDER BY ROW_NUMBER() OVER(PARTITION BY LEFT(ItemCode,3) ORDER BY Itemcode DESC) 

答案 1 :(得分:1)

感谢@jarlh,我使用x来实现我的需要。

如果有人有更通用的方法,可以更容易扩展到更多标准,请发一个答案,我会接受它。欢呼声。

UNION

答案 2 :(得分:1)

您可以在CTE中使用ROW_NUMBER()获得更通用的表单:

;With Ordered as (
    select
        *,
        ROW_NUMBER() OVER (
            PARTITION BY SUBSTRING(ItemCode,1,3)
            ORDER BY ItemCode desc) as rn
    from
        Table
    where
        ItemCode like '987%' or
        ItemCode like '123%'
)
select *
from Ordered
where rn = 1

正如我在评论中提到的那样,如果可能的话,我会更改结构,以便单独存储ItemCode元素,这样可以使更简单的内部查询形式更容易受益于索引。例如。类似的东西:

;With Ordered as (
    select
        *,
        ROW_NUMBER() OVER (
            PARTITION BY ItemCode_Prefix
            ORDER BY ItemCode_Suffix desc) as rn
    from
        Table
    where
        ItemCode_Prefix in (987,123)
)
select *
from Ordered
where rn = 1

答案 3 :(得分:1)

基于ROW_NUMBER()函数的完整解决方案:

response.getWriter()