Sql ITARY排序,不保证“最高”将被分配到行号1。OP在上面进行了注释,只希望“按字典顺序最大,只需按1描述添加顺序即可”。我认为OP不想按itemCode排序。但是,order by 1 DESC时,order by子句使用1指示SELECT子句中的第一列

Sql ITARY排序,不保证“最高”将被分配到行号1。OP在上面进行了注释,只希望“按字典顺序最大,只需按1描述添加顺序即可”。我认为OP不想按itemCode排序。但是,order by 1 DESC时,order by子句使用1指示SELECT子句中的第一列,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,ITARY排序,不保证“最高”将被分配到行号1。OP在上面进行了注释,只希望“按字典顺序最大,只需按1描述添加顺序即可”。我认为OP不想按itemCode排序。但是,order by 1 DESC时,order by子句使用1指示SELECT子句中的第一列。也就是说,他们的查询实际上是在ItemCode列上进行排序。您的查询为每一行提供相同的常量值进行排序,因此是任意的。系统试图通过在window子句中不允许按1 DESC进行排序来帮助您避免错误。使用(选择1)而不是1只是诱使优化器不产生错误,


ITARY排序,不保证“最高”将被分配到行号1。OP在上面进行了注释,只希望“按字典顺序最大,只需按1描述添加顺序即可”。我认为OP不想按itemCode排序。但是,
order by 1 DESC
时,
order by
子句使用
1
指示
SELECT
子句中的第一列。也就是说,他们的查询实际上是在
ItemCode
列上进行排序。您的查询为每一行提供相同的常量值进行排序,因此是任意的。系统试图通过在window子句中不允许按1 DESC进行排序来帮助您避免错误。使用
(选择1)
而不是
1
只是诱使优化器不产生错误,但逻辑错误仍然存在。Ok。我认为不清楚如何获得最大的项目代码。ItemCode是varchar,OP应该使它更清晰。@TriV谢谢,我已经尝试了你的代码,但正如Damien所说,它返回两行,这给了我升序结果。但是,如果我将
SELECT 1
更改为
ItemCode
,它将返回正确的结果。这给了你一个投票权,但我仍然认为这个简短、干净的解决方案比Damien的CTE解决方案好(我不熟悉CTE…)谢谢,它工作得很好!我不熟悉CTE,它是否比@Triv的解决方案更好,后者看起来相似,但更干净、更短?@shole-一旦订单确定,它们可能会产生相同的执行计划。总的来说,我倾向于将CTE作为一种更通用的机制——TriVs的答案依赖于能够创建一个在
ORDER BY
子句中可接受的表达式,而我的则分别定义行号,然后可以应用任意的附加转换。在一天结束的时候,选择对你来说最合适并且性能可以接受的东西。如果你想在备选方案中进行选择,请经常比较计划,看看它们是否在任何方面确实不同。谢谢,它非常有效!我不熟悉CTE,它是否比@Triv的解决方案更好,后者看起来相似,但更干净、更短?@shole-一旦订单确定,它们可能会产生相同的执行计划。总的来说,我倾向于将CTE作为一种更通用的机制——TriVs的答案依赖于能够创建一个在
ORDER BY
子句中可接受的表达式,而我的则分别定义行号,然后可以应用任意的附加转换。在一天结束的时候,选择对你来说最合适并且性能可以接受的东西。如果你想在备选方案中进行选择,请经常比较计划,看看它们是否在任何方面确实不同。
SELECT TOP 1 ItemCode From Table 
WHERE ItemCode like '987%' OR ItemCode like '123%'
ORDER BY 1 DESC
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) 
;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
;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
use tempdb;
go

-- Test data
create table #test_data
(ItemCode char(8) not null);

insert into #test_data
values 
  ('097-1234'),
  ('097-1243'),
  ('097-7890'),
  ('012-1234'),
  ('912-1234'),
  ('123-1234'),  -- second max for '987,123'
  ('123-1234'),
  ('123-0001'),
  ('123-0932'),
  ('987-1234'),
  ('987-5643'),
  ('987-7890'),  -- first max for '987,123'
  ('000-7890');
go
-- Test data

-- Code
create proc dbo.top_n_from_m
  @criterias varchar(max)
as
  set nocount on;

  declare @crs table 
    (id int not null identity (1, 1) primary key,
     string char(3) not null);

  insert into @crs (string)
  select value
  from string_split(@criterias, ',')

  select t.ItemCode
  from 
    (select t.ItemCode,
            c.id, 
            row_id = row_number() over (partition by c.id order by t.ItemCode desc)
    from #test_data as t
      join @crs as c on t.ItemCode like c.string + '-%') as t
  where t.row_id = 1
  order by t.id
go
-- Code

-- Test
execute dbo.top_n_from_m @criterias = '987,123'

select ItemCode
from #test_data
order by ItemCode
-- Test

-- Clear
drop table #test_data;
drop proc dbo.top_n_from_m;
-- Clear