Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从一条记录中拆分数据是一个特定的列T-SQL_Sql Server_Function_Split_Substring_Max - Fatal编程技术网

Sql server 从一条记录中拆分数据是一个特定的列T-SQL

Sql server 从一条记录中拆分数据是一个特定的列T-SQL,sql-server,function,split,substring,max,Sql Server,Function,Split,Substring,Max,我正在处理一个旧的遗留数据库,它是从Oracle导入SQL Server 2012的。我有一个名为inOrders的下表,其中包括一个名为OrderID的列,类型为varchar8 插入的数据示例如下: A04-05 | B81-02 | C02-01 A01-01 | B95-01 | C99-05 A02-02 | B06-07 | C03-02 A98-06 | B10-01 | C17-01 A78-07 | B02-03 | C15-03 A79

我正在处理一个旧的遗留数据库,它是从Oracle导入SQL Server 2012的。我有一个名为inOrders的下表,其中包括一个名为OrderID的列,类型为varchar8

插入的数据示例如下:

A04-05  |  B81-02  |  C02-01
A01-01  |  B95-01  |  C99-05
A02-02  |  B06-07  |  C03-02
A98-06  |  B10-01  |  C17-01
A78-07  |  B02-03  |  C15-03
A79-01  |  B02-01  |  C78-06
第一个字母=订单类型,下一个2位数=年份,最后一个2位数=该年份内的订单数量

所以我把所有数据分成3列:不存储,只显示

select 
    orderid,
    substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype,
    right(max(datepart(yyyy, '01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year,
    max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum
from 
    ins.insorders
where 
    orderid is not null
group by 
    substring(orderid, 0, patindex('%[0-9]%', orderid)), orderid
order by 
    ordtype
它看起来是这样的:

OrderID  |  OrderType  |  OrderYear  | OrderNum
---------+-------------+-------------+----------
A04-05   |  A          |  04         |  05
A01-01   |  A          |  01         |  01
B10-03   |  B          |  10         |  03
B95-01   |  B          |  95         |  01
etc....
但现在我只想为所有订单类型选择最大值:仅显示字母A的最大值,显示字母B的最大值,等等。我的意思是最大值,我的意思是从字母A我需要显示最近一年和最新订单号。因此,如果我有A04-01和A04-02,只需显示A04-02

如果我可以看到以下内容,我需要修改我的查询:

OrderID  |  OrderType  |  OrderYear  | OrderNum
---------+-------------+-------------+----------
A04-05   |  A          |  04         |  05
B10-03   |  B          |  10         |  03
C17-01   |  C          |  17         |  01

谢谢您,我将非常感谢您的帮助。

数据表示得很糟糕,我只有一种方法来解释它,我们需要做很多假设:

with cte_example
as
( your query )
select OrderID
       ,OrderType
       ,OrderYear
       ,OrderNum
from
(select *, row_number() over(partition by OrderType order by OrderYear DESC) rn      
from cte_example
where OrderYear <= right(year(getdate()),2)) t1
where t1.rn = 1
既然您已经有了一个提取信息的查询,我就不必麻烦更改它了。我们将您的查询包装在一个CTE中,从中进行查询,并应用row_number函数来确定哪种OrderType具有最新的OrderYear,以及它的OrderNum和OrderID

现在棘手的部分是,假设我在你的原始帖子上的评论是真实的,那么对OrderType B使用任何类型的聚合都将返回95,因为它在数字上是最大的

我们假设没有任何订单日期大于当前年份,任何大于当前年份的日期都是在90年代,使用以下语句:其中OrderYear 因此,通过筛选,我们可以看到每个订单类型的最新年份。。。希望这有帮助


是我构建的rextester测试,用于处理您的查询,以防您想尝试它。

您可以尝试下面的方法。将原始查询用作cte,并根据订单年份和订单号为每组订单类型分配行号。然后获取每种订单类型的最大行数1

这个小小的DATEPARTyyyy,'01/01/'+OrderYear将确保我们得到正确的年份,因此95是1995年,10是2010年,等等

   ;WITH cte 
    AS (
    select orderid,
    substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype,
    right(max(datepart(yyyy,'01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year,
    max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum
    from ins.insorders
    where orderid is not null
    group by substring(orderid, 0, patindex('%[0-9]%', orderid)), orderid
    )

SELECT *
FROM
  (SELECT 
        *
      , ROW_NUMBER() OVER (PARTITION BY OrderType ORDER BY DATEPART(yyyy,('01/01/' + OrderYear)) DESC, OrderNum DESC) AS RowNum
    FROM cte) t
WHERE t.RowNum = 1

我认为您最初的查询几乎正是您所需要的,只是您需要使用MAXOrderID,而不是按它分组

declare @Something table
(
    orderid varchar(6)
)

insert @Something
(
    orderid
) values
('A04-05'), ('B81-02'), ('C02-01'),
('A01-01'), ('B95-01'), ('C99-05'),
('A02-02'), ('B06-07'), ('C03-02'),
('A98-06'), ('B10-01'), ('C17-01'),
('A78-07'), ('B02-03'), ('C15-03'),
('A79-01'), ('B02-01'), ('C78-06')

select max(orderid),
substring(orderid, 0, patindex('%[0-9]%', orderid)) as ordtype,
right(max(datepart(yyyy,'01/01/' + substring(orderid, patindex('%[0-9]-%', orderid) - 1, 2))),2) as year,
max(substring(orderid, patindex('%-[0-9]%', orderid) + 1, 2)) as ordnum
from myTable
where orderid is not null
group by substring(orderid, 0, patindex('%[0-9]%', orderid))
order by ordtype

这有点奇怪,所以我假设在B10-03 OrderYear中显示的是10而不是95,因为10表示为2010,95表示为1995?这难道不会像使用MAXorderid和从组中删除orderid那样简单吗?