2 votes

Joindre deux tables sur la base de la condition de la colonne

Dans MS SQL Server, il existe deux tables, "T1" et "T2", ayant un champ commun "ID (PK)", où l'ID est unique, mais pour le même enregistrement d'ID, la date dans T1 et T2 peut être différente, et le contenu de ABC ou DEF peut également être différent :

----------
T1:
----------
ID   Date     A     B      C
----------
55   12/1/17  Jim  Smith  Male
77   12/2/17  Jim  Green  Male
99   10/3/17  Kate Lee    Male

T2:
----------
ID   Date       D    E     F
----------
55   12/1/17  Jim  Smith  Male
77   10/2/16  James  Jr   Male
99   12/25/17 Kathy  Lee  Male

J'aimerais avoir une sorte de table jointe basée sur l'ID et choisissant ABC ou DEF en fonction de la date la plus récente, dans ce cas, j'aimerais avoir

----------
ID   Date     join1| join2 | join3
----------
55   12/1/17  Jim  Smith  Male
77   12/2/17  Jim  Green  Male
99   12/25/17 Kathy Lee   Male

Est-ce possible ?

Ce que j'ai trouvé jusqu'à présent est un peu fastidieux : j'ai d'abord fait une jonction extérieure complète :

select * from T1 full outer join  T2 on T1.ID = T2.ID

de disposer des éléments suivants :


ID   Date     A     B      C     Date2     D       E       F
----------
55   12/1/17  Jim  Smith  Male   12/1/17  Jim    Smith   Male
77   12/2/17  Jim  Green  Male   10/2/16  James   Jr     Male
99   10/3/17  Kate Lee    Male   12/25/17 Kathy   Lee    Male

J'ai ensuite essayé d'utiliser case when then else pour sélectionner les champs ABC ou DEF, ce qui est assez laid et je m'inquiète des performances.

select T1.ID, 
        case when T1.Date > T2.Date then T1.Date else T2.Date END as Date 
        case when T1.Date > T2.Date then T1.A else T2.D END as Join1
        case when T1.Date > T2.Date then T1.B else T2.E END as Joni2
        case when T1.Date > T2.Date then T1.C else T2.F END as Join3
from RESULT_TABLE

Est-il possible de faire quelque chose comme ce qui suit :

    select T1.ID,
           case when T1.Date > T2.Date then 
                T1.Date, T1.A as Join1, T1.B as Join2, T1.C as Join3
           else
                T2.Date, T2.D as Join1 , T2.E as Join2, T2.F as Join3
           END 
from RESULT_TABLE

0voto

Gordon Linoff Points 213350

Une méthode utilise case :

select t1.id,
       (case when t1.date >= t2.date then t1.date else t2.date end) as date,
       (case when t1.date >= t2.date then t1.a else t2.a end) as a,
       (case when t1.date >= t2.date then t1.b else t2.a end) as b,
       (case when t1.date >= t2.date then t1.c else t2.a end) as c
from t1 join
     t2
     on t1.id = t2.id;

Si vous n'aimez pas tous les case vous pouvez le faire :

select t1.*
from t1 join
     t2
     on t1.id = t2.id and t1.date >= t2.date
union all
select t2.*
from t1 join
     t2
     on t1.id = t2.id and t1.date < t2.date;

Note : Il est préférable d'énumérer les colonnes plutôt que d'utiliser la fonction select * . Cette version suppose que les deux tables ont exactement les mêmes colonnes, dans le même ordre, avec des types compatibles.

0voto

Charles Bretana Points 59899

Bien sûr,

Select t1.Id, 
  case when t1.Date > t2.Date then t1.Date else t2.Date end date,
  case when t1.Date > t2.Date then t1.A else t2.D end AD,
  case when t1.Date > t2.Date then t1.B else t2.E end BE,
  case when t1.Date > t2.Date then t1.C else t2.F end CF

From T1 join T2 on t2.Id = t1.Id

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X