Помощь с SQL — объединение двух строк в одну строку

У меня есть интересная проблема с SQL, с которой мне нужна помощь.

Вот пример набора данных:

Warehouse  DateStamp   TimeStamp  ItemNumber  ID
    A       8/1/2009    10001         abc      1
    B       8/1/2009    10002         abc      1 
    A       8/3/2009    12144         qrs      5
    C       8/3/2009    12143         qrs      5
    D       8/5/2009    6754          xyz      6
    B       8/5/2009    6755          xyz      6

Этот набор данных представляет перемещение запасов между двумя складами. Каждая передача представляет две записи, и эти две записи передачи всегда имеют одинаковый ItemNumber, DateStamp и ID. Значения TimeStamp для двух записей о перемещении всегда имеют разность, равную 1, где меньшее значение TimeStamp представляет запись исходного хранилища, а большее значение TimeStamp представляет запись хранилища назначения.

Используя пример набора данных выше, вот набор результатов запроса, который мне нужен:

Warehouse_Source  Warehouse_Destination  ItemNumber  DateStamp
    A                B                      abc       8/1/2009
    C                A                      qrs       8/3/2009
    D                B                      xyz       8/5/2009   

Я могу написать код для получения желаемого набора результатов, но мне было интересно, возможна ли эта комбинация записей с помощью SQL. Я использую SQL Server 2005 в качестве базовой базы данных. Мне также нужно добавить предложение WHERE в SQL, чтобы, например, я мог искать на Warehouse_Source = A. И нет, я не могу изменить модель данных ;).

Любые советы высоко ценится!

С уважением, Марк


person Mark Lansdown    schedule 01.09.2009    source источник


Ответы (1)


Отметка,

Вот как вы можете сделать это с помощью row_number и PIVOT. С кластеризованным индексом или первичным ключом в столбцах, как я предлагаю, он будет использовать прямолинейный план запроса без операции сортировки, поэтому будет особенно эффективным.

create table T(
  Warehouse char,
  DateStamp datetime,
  TimeStamp int,
  ItemNumber varchar(10),
  ID int,
  primary key(ItemNumber,DateStamp,ID,TimeStamp)
);
insert into T values ('A','20090801','10001','abc','1');
insert into T values ('B','20090801','10002','abc','1'); 
insert into T values ('A','20090803','12144','qrs','5');
insert into T values ('C','20090803','12143','qrs','5');
insert into T values ('D','20090805','6754','xyz','6');
insert into T values ('B','20090805','6755','xyz','6');

with Tpaired(Warehouse,DateStamp,TimeStamp,ItemNumber,ID,rk) as (
  select
    Warehouse,DateStamp,TimeStamp,ItemNumber,ID,
    row_number() over (
      partition by ItemNumber,DateStamp,ID
      order by TimeStamp
    )
  from T
)
  select
    max([1]) as Warehouse_Source,
    max([2]) as Warehouse_Destination,
    ItemNumber,
    DateStamp
  from Tpaired
  pivot (
    max(Warehouse) for rk in ([1],[2])
  ) as P
  group by ItemNumber, DateStamp, ID;
go

drop table T;
person Steve Kass    schedule 02.09.2009