2014-09-17 3 views
0

Tom aime les sports. Chaque mois, il se repose un peu et joue son sport favori. Il change le jeu au cours du mois et son historique des changements est présenté dans le tableau. Défi: Quel est le premier et dernier sport favori joué par Tom?Sql requête pour la situation suivante

 Tom Favourite Sports 
    ---------------------- 
Month PreviousSport CurrentSport 
JAN  REST   CRICKET 
JAN  CRICKET   RUGBY 
JAN  RUGBY   VOLLEYBALL 
JAN  VOLLEYBALL  FOOTBALL 
JAN  FOOTBALL  TENNIS 
JAN  TENNIS   RUGBY 
FEB  REST   KAYAKING 
FEB  KAYAKING  SNOWBOARDING 
FEB  SNOWBOARDING SKATING 
FEB  SKATING   RAFTING 
FEB  RAFTING   KAYAKING 
MAR  REST   RACING 
MAR  RACING   GLIDING 
MAR  GLIDING   SKYDIVING 

Et la sortie devrait être

Month FirstSport LastSport 
JAN  CRICKET  RUGBY 
FEB  KAYAKING KAYAKING 
MAR  RACING  SKYDIVING 

CHANGEMENT: Légère modification à la table source

MTH PREVIOUS_SPORT CURRENT_SPORT 
JAN VOLLEYBALL  FOOTBALL 
FEB REST   KAYAKING 
MAR REST   RACING 
JAN CRICKET   RUGBY 
FEB SNOWBOARDING SKATING 
MAR RACING   GLIDING 
JAN RUGBY   VOLLEYBALL 
FEB SKATING   RAFTING 
MAR GLIDING   SKYDIVING 
JAN FOOTBALL  TENNIS 
FEB RAFTING   KAYAKING 
JAN TENNIS   RUGBY 
JAN REST   CRICKET 

Maintenant, comment puis-je obtenir la sortie précédente?

Merci d'avance.

+0

Peut-être que je manque quelque chose, mais est-il nécessaire de maintenir la relation avec le sport précédent? Qu'en est-il juste d'avoir Date et CurrentSport? – orjan

Répondre

2

Je viens de considérer la colonne d'ID pour la table, nous pouvons l'éviter & convertir Jan/Feb/Mars en tant que numéros de mois & aller de l'avant sans colonne ID. Mais pour une réponse rapide, c'est ça !!!

Select Main.[Month],F.CurrentSport,L.CurrentSport from 
(
    Select a.[Month],min(r) fSport ,max(r) lSport from 
     (select * ,ROW_NUMBER() over (Partition by Month order by ID) as R 
      from Tom 

     )a 
    group by a.[Month] 
)as Main  
inner join 
    (
     select *, ROW_NUMBER() over (Partition by Month order by ID) as R 
     from Tom 
    )as F on F.R = Main.fSport and f.[Month] = Main.[Month] 
inner join 
    (
     select *, ROW_NUMBER() over (Partition by Month order by ID) as R 
     from Tom 
    )as L on L.R = Main.lSport and L.[Month] = Main.[Month] 
order by F.ID 

Voir Fiddle DEMO HERE

Une variante plus, en évitant ROW_NUMBER plusieurs fois à l'aide de & CTE. Je pense que cela devrait être plus rapide que le précédent.

;With CTE as 
(
select ID,[Month] as M,CurrentSport as Sport 
    , ROW_NUMBER() over (Partition by Month order by ID) as R 
from Tom 
), CTE1 as 
(
Select M, Min(R) as FS ,Max(R) as LS from CTE 
group by M 
) 
Select CTE1.M,F.Sport as First,L.Sport as Last from CTE1 
inner join CTE as F on F.R = CTE1.FS and F.M = CTE1.M 
inner join CTE as L on L.R = CTE1.LS and L.M = CTE1.M 
order by L.ID asc 

Voir la démo HERE

+0

Merci, mais la colonne LastSport est manquante dans la sortie du violon. – Leo

+0

Merci! J'ai mis à jour la démo, le problème était que j'avais gardé le même nom de colonne pour les deux dernières colonnes. – AK47

+0

Superbe. Merci. – Leo

0

Je ne pense pas que nous avons besoin de la colonne ID en tant que tel. Nous pouvons travailler avec RowNumber.

Il devrait arriver comme ça:

SELECT Mintmp.mnth, 
     Mintmp.currentsport AS FirstSport, 
     MaxTmp.currentsport AS CurrentSport 
FROM (SELECT Row_number() 
       OVER( 
        partition BY mnth 
        ORDER BY mnth) AS RowNum, 
       * 
     FROM @T1) MinTmp 
     INNER JOIN (SELECT Min(rownum) AS MinRow, 
          mnth, 
          Max(rownum) AS MaxRow 
        FROM (SELECT Row_number() 
            OVER( 
             partition BY mnth 
             ORDER BY mnth) AS RowNum, 
            * 
          FROM @T1) tmp 
        GROUP BY mnth) grpTable 
       ON grpTable.minrow = MinTmp.rownum 
        AND grpTable.mnth = MinTmp.mnth 
     INNER JOIN (SELECT Row_number() 
          OVER( 
           partition BY mnth 
           ORDER BY mnth) AS RowNum, 
          * 
        FROM @T1) MaxTmp 
       ON Maxtmp.rownum = grpTable.maxrow 
        AND Maxtmp.mnth = grpTable.mnth 
+0

Cool! Merci mec. – Leo

Questions connexes