【问题标题】:SQL Server - Group by - Additional columnSQL Server - 分组依据 - 附加列
【发布时间】:2018-11-27 15:12:40
【问题描述】:

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

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 子句中的列中的不同值。不确定这种方法在这里是否也有用。

提前谢谢大家!

问候, 托比

附加说明,基于 cmets 和 @junketsu 的回答:
后台有一列Target,无法访问。它的内容始终是 SubTarget 的一个分区——反之亦然:SubTarget 通过在字符串末尾添加更多字符来进一步向 Target 添加一些细节。也就是说,这两个值分别不限于两个或三个字符。如果是这样,我可以轻松使用 substring 函数。

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

再次感谢, 托比

【问题讨论】:

  • 一个组的孩子数量限制是多少是2
  • 在前端应用中处理这个会容易得多。
  • 当你有 XYZ 和 ABC 时会发生什么?你什么都不回吗?像您尝试的那样比较子字符串充其量只会非常痛苦。
  • ABA 变成了AB,因为A 不断重复。如果我是对的,那么请告诉我们,为什么 XYAXYB 更改为 XY。或者用一些例子来解释你的登录。
  • 非常有趣的cmets,谢谢大家的贡献! @SanalSunny,理论上没有限制,实际上没有孩子的范围从 1 到 10。

标签: sql sql-server group-by


【解决方案1】:

我无法理解您的附加说明和第三个示例(订单#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 中的模式并获得最大长度。因为,基本字符串会出现很多次。

例如:TruckTrunck123、Trunck456、Trunck789、Trunck123 来得更多。

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

3)。 ma​​xcount:我得到最大计数,由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】:

    你好,先生

    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
    

    【讨论】:

    • 喜欢使用保留字顺便说一句...不是。只是一个建议 'Order', 'Description' , Rank... sql server 的保留字。最好不要使用它们。如果你真的觉得有必要在后面加上下划线或其他东西:)
    • 这不符合问题的要求。
    • 对不起,按 [order] asc 订购
    • @TabAlleman 是正确的,SubTarget 列中的字符串长度不固定,可以在 3 到 20 个字符之间变化。此外,相同的部分可以从任何位置变化,直到倒数第二个。
    • 那么我建议你开始 tweeking 代码 :) 在这里指导。样品集得到你想要的。休息是你的任务。
    猜你喜欢
    • 2011-02-20
    • 2011-06-09
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多