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非常感谢您!这正是我解决这个问题所需要的!我将该解决方案应用到我的表格中,得到了我想要的确切结果。你是个救生员