SQL Server - Группировать по - Дополнительный столбец - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть проблема, которую я едва могу выразить словами, и поэтому не смог найти решение до создания этого сообщения.Пожалуйста, прости меня, если об этом уже спрашивали.Позвольте мне проиллюстрировать ввод и желаемый вывод:

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 (слева направо для записи), пока ониmatch (и отбросить все остальное):

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

Однажды я нашел в сети какой-то аккуратный код для объединения различных значений из столбца, не входящего в предложение group, используя STUFF и FOR XML PATH.Не уверен, что этот подход может быть полезен и здесь.

Спасибо всем заранее!

С уважением, Тоби

Дополнительные заметки, основанные на комментариях и ответе от @junketsu:
На заднем плане есть столбец Цель, который недоступен.Его содержимое всегда является разделом SubTarget - наоборот: SubTarget дополнительно добавляет некоторые детали в Target, добавляя больше символов в конец строки.При этом оба значения не ограничены двумя или тремя символами соответственно.Если это так, я мог бы легко использовать функцию подстроки.

Третий пример (Приказ № 19) может сбить с толку.Я включил этот пример, чтобы показать, что будет хорошо для всей строки в результате, если в заказе будет только одна операция.Другим примером может быть: заказ 5 с операциями Op1, Op2, Op3 и SubTarget Truck123, Truck456, Truck789 и Truck 123. Это должно привести к «Truck» в качестве результата.Повторение Truck123 не является ошибкой.Надеюсь, это прояснит ситуацию.
В конце я хочу приблизиться к фактическому содержанию столбца Target, поскольку его нельзя включить в запрос.

Еще раз спасибо, Тоби

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Я не могу понять ваши Дополнительные примечания и третий пример (Заказ № 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 .

И Грузовик длина больше Тр, Тру, Трук .

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
0 голосов
/ 27 ноября 2018

Вот, пожалуйста, сэр

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
...