2009-09-01 8 views
0

J'ai un problème SQL intéressant que j'ai besoin d'aide.Aide Avec SQL - Combinaison de deux lignes en une seule ligne

Voici l'ensemble de données de l'échantillon:

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 

Cet ensemble de données représente les transferts d'inventaire entre deux entrepôts. Deux enregistrements représentent chaque transfert et ces deux enregistrements de transfert ont toujours les mêmes ItemNumber, DateStamp et ID. Les valeurs TimeStamp pour les deux enregistrements de transfert ont toujours une différence de 1, où le plus petit TimeStamp représente l'enregistrement de l'entrepôt source et le plus grand TimeStamp représente l'enregistrement de l'entrepôt de destination.

Utilisation de l'ensemble de données exemple ci-dessus, est ici le jeu de résultats de la requête que j'ai besoin:

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

Je peux écrire du code pour produire le jeu de résultat souhaité, mais je me demandais si cette combinaison d'enregistrement a été possible grâce à SQL . J'utilise SQL Server 2005 comme base de données sous-jacente. J'ai aussi besoin d'ajouter une clause WHERE au SQL, pour que par exemple, je puisse chercher sur Warehouse_Source = A. Et non, je ne peux pas changer le modèle de données;).

Un conseil est grandement apprécié!

Cordialement, Mark

Répondre

7
SELECT source.Warehouse as Warehouse_Source 
, dest.Warehouse as Warehouse_Destination 
, source.ItemNumber 
, source.DateStamp 
FROM table source 
JOIN table dest ON source.ID = dest.ID 
    AND source.ItemNumber = dest.ItemNumber 
    AND source.DateStamp = dest.DateStamp 
    AND source.TimeStamp = dest.TimeStamp + 1 
+0

Parfait! Je vous remercie... –

0

Mark,

Voici comment vous pouvez le faire avec row_number et PIVOT. Avec un index clusterisé ou une clé primaire sur les colonnes comme je le suggère, il utilisera un plan de requête linéaire sans opération de tri, donc particulièrement efficace.

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; 
Questions connexes