Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запрос  [new]
IDVT
Member

Откуда:
Сообщений: 313
Всем привет!

Прошу помощи, совсем застрял.....
Тестовый набор данных:
declare @test table ( CustId VarChar(20)
                    , Ship   VarChar(20)
                    , Inn    VarChar(20)
                    , Kpp    VarChar(20)
                    , Xcol   as  Inn + '-' + Kpp)
insert into @test                                -- вхождения                     -- ожидаемый результат
       values ( 'Cust 1',  'Ship 1', '44', '32') --                               New Ship 1
            , ( 'Cust 2',  'Ship 1', '32', '44') --                               New Ship 1
            , ( 'Cust 3',  'Ship 1', '22', '33') -- *Ship 5                       New Ship 1
            , ( 'Cust 4',  'Ship 1', '11', '11') -- *Ship 3                       New Ship 1

            , ( 'Cust 5',  'Ship 2', '13', '13') --                               New Ship 2
            , ( 'Cust 6',  'Ship 2', '33', '13') --                               New Ship 2
            , ( 'Cust 7',  'Ship 2', '72', '12') --                               New Ship 2
            , ( 'Cust 8',  'Ship 2', '99', '10') --                               New Ship 2

            , ( 'Cust 9',  'Ship 3', '11', '11') -- *Ship 1,                      New Ship 1
            , ( 'Cust 10', 'Ship 3', '12', '12') --                               New Ship 1

            , ( 'Cust 11', 'Ship 4', '14', '14') --                               New Ship 3
            , ( 'Cust 12', 'Ship 4', '15', '15') --                               New Ship 3
            , ( 'Cust 13', 'Ship 4', '16', '15') --                               New Ship 3
            , ( 'Cust 14', 'Ship 4', '17', '15') --                               New Ship 3

            , ( 'Cust 14', 'Ship 5', '18', '14') --                               New Ship 1
            , ( 'Cust 15', 'Ship 5', '19', '19') --                               New Ship 1
            , ( 'Cust 16', 'Ship 5', '20', '20') --                               New Ship 1
            , ( 'Cust 17', 'Ship 5', '22', '33') -- *Ship 1                       New Ship 1

            , ( 'Cust 18', 'Ship 6', '22', '22') -- *Ship 7                       New Ship 4
            , ( 'Cust 19', 'Ship 6', '18', '18') --                               New Ship 4

            , ( 'Cust 20', 'Ship 7', '22', '22') -- *Ship 6                       New Ship 4
            , ( 'Cust 21', 'Ship 7', '23', '23') --                               New Ship 4


Мне необходимо собрать новые связи (NewShip) из существующих связей (Ship) по клиентам (CustId), алгоритм таков:
Если у клиентов из разных связей есть совпадение по полю Xcol, то мне нужно соединить эти связи в одну, в противном случае оставить существующую. Пытался сделать через "for xml path('')" во вложенном запросе, но это не то, пните в нужное русло =)
23 авг 17, 12:16    [20743618]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
aleks222
Guest
Потому и не смог, что внятно изложить не можешь.

Кто на ком стоял?
23 авг 17, 12:36    [20743699]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
IDVT
Member

Откуда:
Сообщений: 313
aleks222
Потому и не смог, что внятно изложить не можешь.

Кто на ком стоял?

С эти проблема, =)

на примере группа клиентов "Ship 1", некоторые клиенты имеют равнозначное значение в колонке "Xcol" с клиентами из групп "Ship 5" и "Ship 3" в этом случае мне нужно объединить три группы в одну.

Вот эти клиенты:
Select t.CustId
     , t.Ship
     , dt.Ship
     , dt.CustId
from @test as t inner join @test as dt
     on t.Xcol = dt.Xcol
	    and t.Ship <> dt.Ship
where t.Ship = 'Ship 1'
23 авг 17, 12:46    [20743742]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
buven
Member

Откуда:
Сообщений: 792
IDVT,
Вам вот из этого
			Select t.CustId
     , t.Ship
     , dt.Ship
     , dt.CustId
from @test as t inner join @test as dt
     on t.Xcol = dt.Xcol
	    and t.CustId <> dt.CustId


Нужно убрать повторы типа

Cust 3, Ship 1, Ship 5, Cust 17
Cust 17, Ship 5, Ship 1, Cust 3


?
23 авг 17, 13:07    [20743814]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
`
Guest
IDVT,

select * 
from @test t1
outer apply (select top 1 Ship
			from @test t2 where t2.Xcol in (select t3.Xcol from @test t3 where t3.Ship=t1.Ship)
			order by Ship) a
23 авг 17, 13:13    [20743839]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
aleks222
Guest
declare @test table ( CustId int
                    , Ship   int
                    , Inn    VarChar(20)
                    , Kpp    VarChar(20)
                    , MinShip int  )
insert into @test(CustId, Ship, Inn, Kpp)                                -- вхождения                     -- ожидаемый результат
       values ( '1',  '1', '44', '32') --                               New Ship 1
            , ( '2',  '1', '32', '44') --                               New Ship 1
            , ( '3',  '1', '22', '33') -- *Ship 5                       New Ship 1
            , ( '4',  '1', '11', '11') -- *Ship 3                       New Ship 1

            , ( '5',  '2', '13', '13') --                               New Ship 2
            , ( '6',  '2', '33', '13') --                               New Ship 2
            , ( '7',  '2', '72', '12') --                               New Ship 2
            , ( '8',  '2', '99', '10') --                               New Ship 2

            , ( '9',  '3', '11', '11') -- *Ship 1,                      New Ship 1
            , ( '10', '3', '12', '12') --                               New Ship 1

            , ( '11', '4', '14', '14') --                               New Ship 3
            , ( '12', '4', '15', '15') --                               New Ship 3
            , ( '13', '4', '16', '15') --                               New Ship 3
            , ( '14', '4', '17', '15') --                               New Ship 3

            , ( '14', '5', '18', '14') --                               New Ship 1
            , ( '15', '5', '19', '19') --                               New Ship 1
            , ( '16', '5', '20', '20') --                               New Ship 1
            , ( '17', '5', '22', '33') -- *Ship 1                       New Ship 1

            , ( '18', '6', '22', '22') -- *Ship 7                       New Ship 4
            , ( '19', '6', '18', '18') --                               New Ship 4

            , ( '20', '7', '22', '22') -- *Ship 6                       New Ship 4
            , ( '21', '7', '23', '23') --       


update @test set MinShip = Ship;
            
declare @rc int = 1;

while @rc > 0 begin

  update t set MinShip = x.MinShip
    from @test as t
         --inner join ( select Ship, MinShip = min(MinShip) from @test group by Ship ) as x on x.Ship = t.Ship 
         cross apply ( select top(1) MinShip from @test as tt where t.Ship = tt.Ship order by MinShip asc ) as x
    where t.MinShip > x.MinShip;
  
  set @rc = @@ROWCOUNT;

  update t set MinShip = x.MinShip
    from @test as t
         cross apply ( select top(1) MinShip from @test as tt 
                         where tt.Inn = t.Inn and tt.Kpp = t.Kpp and tt.MinShip < t.MinShip 
                         order by tt.MinShip asc ) as x
    where t.MinShip > x.MinShip;
    
  set @rc = @rc + @@ROWCOUNT;

end;

select * from @test;            
23 авг 17, 13:15    [20743847]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
IDVT
Member

Откуда:
Сообщений: 313
Спасибо за помощь!!!!
23 авг 17, 13:29    [20743908]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
aleksrov
Member

Откуда:
Сообщений: 948
IDVT,

А я бы так сделал.
with c as ( 
select t.*, t2.Ship as newship from @test as t 
inner join @test as t2 on 
t.Xcol = t2.Xcol and t.CustId != t2.CustId) 
update c 
set Ship = newship
23 авг 17, 13:38    [20743961]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
`
Guest
select *, dense_rank()over(order by Ship) as gr 
into #t 
from @test

declare @gr int = 2
while 1=1
begin
	update t1 
	set t1.gr=a.gr
	from #t t1
	cross apply (select top 1 gr 
				from #t t2 where t2.Xcol in (select t3.Xcol from #t t3 where t3.Ship=t1.Ship)
				order by gr) a
	where t1.gr=@gr

	if @@ROWCOUNT=0 break

	set @gr=@gr+1
end

select * from #t

drop table #t
23 авг 17, 13:43    [20743988]     Ответить | Цитировать Сообщить модератору
 Re: Запрос  [new]
IDVT
Member

Откуда:
Сообщений: 313
=) по факту Update не нужен, слишком много строк (дешевле перелить в новую таблицу), криво изложил суть мыслей....

Остановился на версии с "outer apply ", но в плане 3 раза выполняется обращение к таблице, буду переписывать листинг, в прицепе суть уловил, большое спасибо за помощь!
23 авг 17, 13:54    [20744045]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить