UNION de 4 tables, GROUP BY NomServeur HAVING MAX(Date)

UNION de 4 tables, GROUP BY NomServeur HAVING MAX(Date) - SQL/NoSQL - Programmation

Marsh Posté le 03-09-2013 à 04:50:49    

Bonjour,
 
Je me permets de vous demander votre aide car malgré de nombreuses recherches, je n'ai pu trouver de solution à mon problème.
 
En quelques mots, j'ai 4 tables (alpha, beta, gamma, delta), chacune contenant 2 colonnes (NomServeur, DateEntree).
Chaque table pouvant contenir plusieurs fois le même nom de serveur (mais alors avec une date d'entrée différentes). Ces même serveurs pouvant également se trouver dans d'autres tables.
 
Ce que j'aimerais obtenir c'est une table avec 3 colonnes:
1) Nom de la table où a été trouvé la date la plus récente pour le serveur nommé en colonne 2.
2) Nom de chaque serveur apparaisant au moins une fois dans une des 4 table
3) Date d'entrée la plus récente trouver pour le serveur nommé en colonne 2.
 
Exemple:
 TABLE |  NomServeur | DateEntree
-------------------------------------------
 ALPHA |  S1  | 2013-02-09
 ALPHA |  S2  | 2013-03-24
 BETA  |  S3  | 2013-07-12
 ALPHA |  S5  | 2013-02-02
 
Explication:
- 1ere ligne: Peu importe si S1 se trouvait sur une ou plusieurs table (et même plusieurs fois dans la même), c'est sur la table BETA que la date la plus récente pour ce serveur a été trouvée et c'est 2013-02-09.
- 2e ligne: Peu importe si S2 se trouvait sur une ou plusieurs table (et même plusieurs fois dans la même), c'est sur la table BETA que la date la plus récente pour ce serveur a été trouvée et c'est 2013-03-24.
- 3e ligne: Peu importe si S3 se trouvait sur une ou plusieurs table (et même plusieurs fois dans la même), c'est sur la table BETA que la date la plus récente pour ce serveur a été trouvée et c'est 2013-07-12.
- Et ainsi de suite...
 
Pour info, en utilisant un GROUP BY sur la TABLE et NomServeur, j'obtiens ceci:
 TABLE |  NomServeur | DateEntree
----------------------------------------------------------
 ALPHA |  S1  | 2013-02-09
BETA  |  S1  | 2013-01-09
 DELTA |  S1  | 2013-01-03

 ALPHA |  S2  | 2013-03-24
 ALPHA |  S3  | 2013-03-30
 BETA  |  S3  | 2013-07-12
 ALPHA |  S5  | 2013-02-02
 
Comme vous pouvez le voir, S1 et S3 sont présent plusieurs fois alors que j'aimerais ne garder que la table dans la date est la plus récente...
J'espère que mes explications sont assez claire pour que vous puissiez m'aider.
 
Merci d'avance.
Solvap
 

Reply

Marsh Posté le 03-09-2013 à 04:50:49   

Reply

Marsh Posté le 03-09-2013 à 08:24:47    

Voila ce que je ferai:

Code :
  1. Declare @Alpha TABLE (NomServer varchar(255) NOT NULL, DateEntree date NOT NULL)
  2. Declare @Beta TABLE (NomServer varchar(255) NOT NULL, DateEntree date NOT NULL)
  3. Declare @Gamma TABLE (NomServer varchar(255) NOT NULL, DateEntree date NOT NULL)
  4. Declare @Delta TABLE (NomServer varchar(255) NOT NULL, DateEntree date NOT NULL)
  5.  
  6. INSERT @Alpha (NomServer, DateEntree) VALUES ('S1', '2013-02-09')
  7. INSERT @Alpha (NomServer, DateEntree) VALUES ('S1', '2013-02-08')
  8. INSERT @Alpha (NomServer, DateEntree) VALUES ('S2', '2013-03-24')
  9. INSERT @Alpha (NomServer, DateEntree) VALUES ('S2', '2013-03-23')
  10. INSERT @Alpha (NomServer, DateEntree) VALUES ('S3', '2013-03-30')
  11. INSERT @Alpha (NomServer, DateEntree) VALUES ('S3', '2013-03-29')
  12. INSERT @Alpha (NomServer, DateEntree) VALUES ('S5', '2013-02-02')
  13. INSERT @Alpha (NomServer, DateEntree) VALUES ('S5', '2013-02-01')
  14.  
  15. INSERT @Beta (NomServer, DateEntree) VALUES ('S1', '2013-01-09')
  16. INSERT @Beta (NomServer, DateEntree) VALUES ('S1', '2013-01-08')
  17. INSERT @Beta (NomServer, DateEntree) VALUES ('S3', '2013-07-12')
  18. INSERT @Beta (NomServer, DateEntree) VALUES ('S3', '2013-07-12')
  19.  
  20.  
  21.  
  22. INSERT @Delta (NomServer, DateEntree) VALUES ('S1', '2013-01-03')
  23. INSERT @Delta (NomServer, DateEntree) VALUES ('S1', '2013-01-02')
  24.  
  25. ;With cte AS
  26. (
  27.     SELECT 'ALPHA' [TABLE], NomServer, Max(DateEntree) DateEntree
  28.     FROM @Alpha
  29.     GROUP BY NomServer
  30.     UNION ALL
  31.     SELECT 'BETA' [TABLE], NomServer, Max(DateEntree) DateEntree
  32.     FROM @Beta
  33.     GROUP BY NomServer
  34.     UNION ALL
  35.     SELECT 'GAMMA' [TABLE], NomServer, Max(DateEntree) DateEntree
  36.     FROM @Gamma
  37.     GROUP BY NomServer
  38.     UNION ALL
  39.     SELECT 'DELTA' [TABLE], NomServer, Max(DateEntree) DateEntree
  40.     FROM @Delta
  41.     GROUP BY NomServer
  42. )
  43. SELECT *
  44. FROM cte a
  45.     JOIN (
  46.         SELECT NomServer, MAX(DateEntree) DateEntree
  47.         FROM cte
  48.         GROUP BY NomServer
  49.          ) b ON b.DateEntree = a.DateEntree AND b.NomServer = a.NomServer
  50. ORDER BY a.NomServer, a.[TABLE]


 
Tu peux évidement remplacer le cte (common table expression) par la query en entier, je voulais juste pas la copier 2x :)

Reply

Marsh Posté le 03-09-2013 à 22:05:39    

Hello Oliiii,
 
Déjà, merci pour ta réponse, que je viens de tester. Malheureusement, les serveurs continuent à apparaitre en double, triple,... car présent sur plus d'une table. Mon objectif est qu'un serveur, même présent sur plusieurs table, n'apparaissent qu'une seule fois, celui provenant de la table ayant la date la plus récente et non d'afficher ce même serveur avec la date la plus récentes pour chaque table. Comme pour ce petit table où le serveur S1 apparait 3 fois car présent dans 3 tables (ALPHA, BETA, DETLA) alors que seul la première ligne devrait être afficher car on voit clairement que c'est dans la table ALPHA que S1 à la date la plus résente. La 2e et 3e ligne ne devraient donc pas s'afficher car pour ce même serveur S1, les date dans BETA et DELTA sont plus ancienne.
ALPHA |  S1  | 2013-02-09
BETA   |  S1  | 2013-01-09
DELTA |  S1  | 2013-01-03
ALPHA |  S2  | 2013-03-24
ALPHA |  S3  | 2013-03-30
BETA   |  S3  | 2013-07-12
ALPHA |  S5  | 2013-02-02
 
J'essaies de penser ce problème différement comme par exemple n'afficher que le nom du serveur et la table où la date pour ce serveur est la plus récente, mais j'avoue que plus j'y pense et plus je m'embrouille ... :-S
 
Des idées ?

Reply

Marsh Posté le 04-09-2013 à 09:30:35    

La solution que je propose fait bien ce que tu veux (c'est pour ça qu'il y a un join de 2x la même query en gros).
Voila le resultat de la query:

Code :
  1. TABLE NomServer DateEntree NomServer DateEntree
  2. ALPHA S1 2013-02-09 S1 2013-02-09
  3. ALPHA S2 2013-03-24 S2 2013-03-24
  4. BETA S3 2013-07-12 S3 2013-07-12
  5. ALPHA S5 2013-02-02 S5 2013-02-02


 
La query sans cte ça donne ça:

Code :
  1. SELECT a.[TABLE], a.NomServer, a.DateEntree
  2. FROM (
  3.    SELECT 'ALPHA' [TABLE], NomServer, Max(DateEntree) DateEntree
  4.    FROM @Alpha
  5.    GROUP BY NomServer
  6.    UNION ALL
  7.    SELECT 'BETA' [TABLE], NomServer, Max(DateEntree) DateEntree
  8.    FROM @Beta
  9.    GROUP BY NomServer
  10.    UNION ALL
  11.    SELECT 'GAMMA' [TABLE], NomServer, Max(DateEntree) DateEntree
  12.    FROM @Gamma
  13.    GROUP BY NomServer
  14.    UNION ALL
  15.    SELECT 'DELTA' [TABLE], NomServer, Max(DateEntree) DateEntree
  16.    FROM @Delta
  17.    GROUP BY NomServer
  18.    ) a
  19.    JOIN (
  20.    SELECT NomServer, MAX(DateEntree) DateEntree
  21.    FROM (
  22.         SELECT 'ALPHA' [TABLE], NomServer, Max(DateEntree) DateEntree
  23.         FROM @Alpha
  24.         GROUP BY NomServer
  25.         UNION ALL
  26.         SELECT 'BETA' [TABLE], NomServer, Max(DateEntree) DateEntree
  27.         FROM @Beta
  28.         GROUP BY NomServer
  29.         UNION ALL
  30.         SELECT 'GAMMA' [TABLE], NomServer, Max(DateEntree) DateEntree
  31.         FROM @Gamma
  32.         GROUP BY NomServer
  33.         UNION ALL
  34.         SELECT 'DELTA' [TABLE], NomServer, Max(DateEntree) DateEntree
  35.         FROM @Delta
  36.         GROUP BY NomServer
  37.         ) c
  38.     GROUP BY NomServer
  39.     ) b ON b.DateEntree = a.DateEntree AND b.NomServer = a.NomServer
  40. ORDER BY a.NomServer, a.[TABLE]


Message édité par Oliiii le 04-09-2013 à 09:34:32
Reply

Marsh Posté le 04-09-2013 à 11:26:02    

Et bien, chapeau bas mon cher Oliiii, cela fonctionne en effet. J'ai juste du m'assurer à mettre les noms des serveurs en majuscule avec UPPER pour éliminer ces doublons qui étaient en fait ces mêmes serveurs mais avec une casse différente, je retrouvais 'S1' et 's1'. Donc, un tout grand merci à toi.
 
Solvap

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed