Sql 查找类似命名项目的最长日期
我试图从数据库中找到一个不同的订单号列表。数据库的布局与此类似:Sql 查找类似命名项目的最长日期,sql,sql-server,Sql,Sql Server,我试图从数据库中找到一个不同的订单号列表。数据库的布局与此类似: orderNumber customer createDate --------------------------------------- 001 123 2019-01-01 002 123 2019-01-23 003 456 2019-03-12 003R1
orderNumber customer createDate
---------------------------------------
001 123 2019-01-01
002 123 2019-01-23
003 456 2019-03-12
003R1 456 2019-03-22
004 456 2019-04-25
005 789 2019-05-21
005A1 789 2019-06-30
005R1 789 2019-07-12
R1是订单的退款,A1是订单的调整
我要查找的结果集是一个不同订单号的列表,其中只包含该订单号的最新版本。例如:
Results
orderNumber customer CreateDate
----------------------------------------
001 123 2019-01-01
002 123 2019-01-23
003R1 456 2019-03-22
004 456 2019-04-25
005R1 789 2019-07-12
我尝试过几种不同的方法,但它们要么返回每个退款或调整,要么不显示其他不同的订单号
select customer, orderNumber, createDate
from (select customer
,orderNumber
,createDate
,ROW_NUMBER() over(partition by customer order by createDate desc) as RowNum
from orders) as T
where RowNum = 1
上述查询的结果如下所示:
orderNumber customer createDate
---------------------------------------
002 123 2019-01-23
003R1 456 2019-03-22
005R1 789 2019-07-12
是否有一种方法可以获得每个订单号以及最新版本的重复订单号。您需要按规范化的orderNumber进行分区,去掉标记。这里我使用的是left和substring,但是您应该使用更健壮的模式匹配来获得第一个数字
select
left(orderNumber, 3) as cleanOrderNumber,
substring(orderNumber, 4, 5) as flag,
customer,
createDate,
row_number() over (partition by left(orderNumber, 3) order by createDate desc) as RowNum
from orders;
cleanOrderNumber flag customer createDate RowNum
001 123 01/01/2019 00:00:00 1
002 123 23/01/2019 00:00:00 1
003 R1 456 22/03/2019 00:00:00 1
003 456 12/03/2019 00:00:00 2
004 456 25/04/2019 00:00:00 1
005 R1 789 12/07/2019 00:00:00 1
005 A1 789 30/06/2019 00:00:00 2
005 789 21/05/2019 00:00:00 3
然后我们可以将其用作CTE,并获得每个订单号的第一行
with cleanOrders as (
select
left(orderNumber, 3) as cleanOrderNumber,
substring(orderNumber, 4, 5) as flag,
customer,
createDate,
row_number() over (partition by left(orderNumber, 3) order by createDate desc) as RowNum
from orders
)
select *
from cleanOrders
where rowNum = 1;
cleanOrderNumber flag customer createDate RowNum
001 123 01/01/2019 00:00:00 1
002 123 23/01/2019 00:00:00 1
003 R1 456 22/03/2019 00:00:00 1
004 456 25/04/2019 00:00:00 1
005 R1 789 12/07/2019 00:00:00 1
请注意,如果orderNumber和flag在表中已经分开,则可以更容易、更快地对它们进行索引。您可以添加新的列,填充它们,并将orderNumber保留为遗留项。我已经让它按如下方式工作。 这是用于DDL和样本数据的 创建表格订单 [orderNumber]varchar5,[customer]int,[createDate]datetime ; 插入订单 [订单号],[客户],[创建日期] 价值观 '001', 123, '2019-01-01 00:00:00', '002', 123, '2019-01-23 00:00:00', '003', 456, '2019-03-12 00:00:00', '003R1',456',2019-03-22 00:00:00', '004', 456, '2019-04-25 00:00:00', '005', 789, '2019-05-21 00:00:00', “005A1”,789,“2019-06-30 00:00:00”, '005R1',789',2019-07-12 00:00:00' ; 这是实际的查询: 以ordersCTE为例 选择*,PATINDEX“%[a-z]”,orderNumber作为firstLetterPosition 从命令到命令 ,计算的订单号为 选择*,CASTCASE firstLetterPosition 当为0时,则为orderNumber ELSE LEFTorderNumber,firstLetterPosition-1 结束时为INT,结束时为ActualLorderNumber 来自ordersCTE ,订购为 选择*,按实际值在分区上的行数按createDate描述为RN的编号顺序 来自ComputedOrderNumber 挑选* 从命令 其中RN=1 这将尝试在忽略orderNumber中的任何字母之前提取标识,然后使用它对数据进行分区
但我强烈建议使用一个适当的列来存储orderNumber的根,每次计算都会非常昂贵。为插入或使用触发器填充的特殊标志(如R1和A1)使用单独的列会更快、更简单。您使用的是哪个SQL数据库?博士后?MySQL?SQL Server?请公布您正在使用的数据库。神谕mySQL?SQL Server?Microsoft SQL Server 2014非常感谢您!这正是我解决这个问题所需要的!我将该解决方案应用到我的表格中,得到了我想要的确切结果。你是个救生员