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