SQL Server-分组依据-附加列

时间:2018-11-27 15:12:41

标签: sql sql-server group-by

我有一个问题,我很难用语言表达,因此在创建此帖子之前无法搜索解决方案。如果您之前曾问过,请原谅我。让我来说明输入和所需的输出:

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中获取所有字符(从左开始写):

Order    Description    SubTarget
12       Order12        AB
18       Order18        XY
19       Order19        KLA
20       Order20        Truck

我曾经在网上发现一些简洁的代码,它们使用STUFF和FOR XML PATH将不在group by子句中的列的不同值连接起来。不确定这种方法在这里是否也有用。

谢谢大家!

关于, 托比

基于@junketsu的评论和回答的其他注释:
后台有“目标”列,该列不可访问。它的内容始终是SubTarget的分区-反之亦然:SubTarget通过在字符串的末尾添加更多字符,进一步为Target添加了一些细节。也就是说,两个值分别不限于两个或三个字符。如果是这样,我可以轻松地使用子字符串函数。

第三个示例(19号订单)可能令人困惑。我包含了此示例,以便表明如果顺序中只有一个操作,那么对整个字符串就可以了。 另一个示例可能是:具有操作Op1,Op2,Op3和子目标Truck123,Truck456,Truck789和Truck 123的订单5。这将产生“卡车”作为结果。 Truck123的重复没有错误。 希望这可以使它更清楚。
最后,我想处理目标列的实际内容,因为它不能包含在查询中。

再次感谢, 托比

2 个答案:

答案 0 :(得分:0)

您好,先生

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

答案 1 :(得分:0)

我无法理解您的附加说明和第三个示例(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)。 计数:我在 cte 中计算模式并获得最大长度。因为,基本字符串来了很多次。

例如:卡车 Trunck123,Trunck456,Trunck789,Trunck123 花费的时间更长。

并且 Truck 的长度大于 Tr,Tru,Truc

3)。 最大数量:我得到最大数量,由数量

返回

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