SQL Server-分组依据-附加列

SQL Server-分组依据-附加列,sql,sql-server,group-by,Sql,Sql Server,Group By,我有一个难以用语言表达的问题,因此在创建此帖子之前无法找到解决方案。如果以前有人问过这个问题,请原谅我。让我举例说明输入和期望的输出: Order Description Operation OperationDescription SubTarget 12 Order12 Op1 Order12, Op1 ABA 12 Order12 Op2 Order12,

我有一个难以用语言表达的问题,因此在创建此帖子之前无法找到解决方案。如果以前有人问过这个问题,请原谅我。让我举例说明输入和期望的输出:

Order    Description    Operation    OperationDescription    SubTarget
12       Order12        Op1          Order12, Op1            ABA
12       Order12        Op2          Order12, Op2            ABB
18       Order18        Op1          Order18, Op1            XYA
18       Order18        Op2          Order18, Op2            XYB
19       Order19        Op1          Order19, Op1            KLA
20       Order20        Op1          Order20, Op1            Truck123
20       Order20        Op2          Order20, Op2            Truck456
20       Order20        Op3          Order20, Op3            Truck789
20       Order20        Op4          Order20, Op4            Truck123
当我查询上面的表并按顺序和描述分组时,我希望从SubTarget(从左到右)获取所有字符,只要它们匹配(并丢弃其余字符):

我曾经在网上找到一些整洁的代码,使用STUFF和FOR XML PATH将group by子句以外的列中的不同值连接起来。不确定这种方法在这里是否也有帮助

提前谢谢大家

问候,, 托比

其他注释,基于@junketsu的评论和回答:
背景中有一个无法访问的列目标。它的内容始终是子目标的一个分区,反之亦然:子目标通过在字符串末尾添加更多字符进一步向目标添加一些细节。也就是说,这两个值不限于两个或三个字符。如果是这样,我可以很容易地使用子字符串函数

第三个例子(Order#19)可能令人困惑。我包含了这个示例,以表明如果订单中只有一个操作,那么对整个字符串的修改就可以了。 另一个例子可能是:带有操作Op1、Op2、Op3和子目标卡车123、卡车456、卡车789和卡车123的订单5。这将产生“卡车”作为结果。Truck123的重复没有错误。 希望这能让事情更清楚。
最后,我想接近目标列的实际内容,因为它不能包含在查询中

再次感谢, 托比给你,好的先生

create table #temp_1
( [order] int null
,Description varchar(15) null
,Operation varchar(30) null
,OperationDescription varchar(30) null
,SubTarget varchar(30) null
)



insert into #temp_1 values

(12       ,'Order12','Op1',          'Order12, Op1'            ,'ABA')
,(12       ,'Order12',' Op2',           'Order12, Op2'            ,'ABB')
,(18       ,'Order18','Op1',           'Order18, Op1'            ,'XYA')
,(18       ,'Order18','Op2',           'Order18, Op2'           ,'XYB')
,(19       ,'Order19','Op1',           'Order19, Op1'           ,'KLA')


select *
from (
select *

,Rank_1 = Row_number() over(partition by SubTarget_1 order by [Order] asc)
from (
select [order],[Description]
--,SubTarget = substring(SubTarget,0,3)
,SubTarget_1 = case when SubTarget like 'a%b%' then 'AB'
when SubTarget like 'x%y%'then 'XY' else SubTarget end
from #temp_1
) a
) b
where Rank_1 = 1
order by [Order] asc

我无法理解你的附加注释和第三个示例(订单19)。我只是为你期望的答案工作

create table #group (Orders int,Description varchar (20),Operation varchar (20)
                     ,OperationDescription varchar (20),SubTarget varchar (20)
                    )

insert into #group values
 (20,'Order20','Op1','Order20, Op1','Truck123')
,(20,'Order20','Op2','Order20, Op2','Truck456')
,(20,'Order20','Op3','Order20, Op3','Truck789')
,(20,'Order20','Op4','Order20, Op4','Truck123')
,(12,'Order12','Op1','Order12 Op1','ABA')
,(12,'Order12','Op2','Order12 Op2','ABB')
,(18,'Order18','Op1','Order18 Op1','XYA')
,(18,'Order18','Op2','Order18 Op2','XYB')
,(19,'Order19','Op1','Order19 Op1','KLA')

select distinct 
gor.Orders, gor.Description, iif (g.c = 1, gor.SubTarget 
, left (gor.subtarget, 2)) subtraget
from (
 select distinct
 orders, Description
 , count (*) c
 from #group group by orders, Description 
) g join #group gor on g.Orders = gor.Orders 
我得到:

Orders      Description     subtraget
12          Order12         AB
18          Order18         XY
19          Order19         KLA
20          Order20         Tr
如果查询需要更新,请还原我

更新1查找更新的查询

select distinct
orders, Description, Operation, OperationDescription
, iif (count (*) over (partition by orders, Description )  = 1, subtarget, 
       left (subtarget, 2)
  ) subtarget
from #group 
更新2

1) cte:首先,我获取所有子目标的子字符串

例如:Truck123->Truck12->Truck1->……->Tr

2) countlen:我计算cte中的图案,并获得最大长度。因为,基本字符串会出现很多次

卡车来的时间比,Trunck123,Trunck456,Trunck789,Trunck123多

卡车长度大于Tr、Tru、Tru

3) maxcount:我获取最大计数,它由countlen返回

4) 。最后,我加入了上面的cte,没有子目标。然后从cte中获取

;with cte as ( 
 select Orders, Description, SubTarget, len (SubTarget) len  from #group  
 union all
 select Orders, Description, left (subtarget, len (SubTarget) - 1)
 , LEN (SubTarget) - 1  from cte  where len > 2
), countlen as (
select
 Orders, Description, SubTarget
 , count (len) over (partition by Orders, Description, SubTarget order by len) count 
 , max (len)  over (partition by Orders, Description, SubTarget order by len) maxlen
 from cte
), maxcount as (
 select Orders, Description, max (count) maxcount from countlen group by Orders, Description
) select distinct
o.Orders, o.Description, c.SubTarget 
from ( 
 select 
 cc.Orders, cc.Description, max (cc.maxlen) maxofmax
 from countlen cc
 join maxcount m
 on cc.Orders = m.Orders and cc.Description = m.Description 
 where m.maxcount = cc.count
 group by cc.Orders, cc.Description 
) o 
join cte c
on o.Orders = c.Orders and o.Description = c.Description and len (c.SubTarget) = o.maxofmax

在一个组中没有孩子的限制是什么?2在前端应用程序中处理这个问题要容易得多。当你有XYZ和ABC时会发生什么?你什么也不退吗?比较你正在尝试的子字符串充其量是非常痛苦的。
ABA
变成了
AB
,因为
A
正在重复它自己。如果我是正确的,那么请告诉我们,为什么
XYA
XYB
更改为
XY
。或者用一些例子来解释你的登录。非常有趣的评论,谢谢大家的贡献@SanalSunny,理论上没有限制,实际上孩子的数量在1到10之间。我喜欢使用保留字,顺便说一句。。。不只是建议“顺序”,“描述”,等级。。。sql server的保留字。最好不要使用它们。如果你真的觉得有必要在后面加下划线或其他什么:)这不符合问题的要求。很抱歉,按[Order]顺序asc@TabAlleman是正确的,列子目标中字符串的长度不是固定的,可以在3到20个字符之间变化。同样,相同的零件可以在任何位置变化,直到最后一个位置。然后我建议您开始在此处编辑代码:)以进行指导。样本集得到您想要的。休息是你的任务。
;with cte as ( 
 select Orders, Description, SubTarget, len (SubTarget) len  from #group  
 union all
 select Orders, Description, left (subtarget, len (SubTarget) - 1)
 , LEN (SubTarget) - 1  from cte  where len > 2
), countlen as (
select
 Orders, Description, SubTarget
 , count (len) over (partition by Orders, Description, SubTarget order by len) count 
 , max (len)  over (partition by Orders, Description, SubTarget order by len) maxlen
 from cte
), maxcount as (
 select Orders, Description, max (count) maxcount from countlen group by Orders, Description
) select distinct
o.Orders, o.Description, c.SubTarget 
from ( 
 select 
 cc.Orders, cc.Description, max (cc.maxlen) maxofmax
 from countlen cc
 join maxcount m
 on cc.Orders = m.Orders and cc.Description = m.Description 
 where m.maxcount = cc.count
 group by cc.Orders, cc.Description 
) o 
join cte c
on o.Orders = c.Orders and o.Description = c.Description and len (c.SubTarget) = o.maxofmax