IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Union de ceux qui n'ont jamais eu de CDD et ceux qui en ont eu. [11gR2]


Sujet :

SQL Oracle

  1. #1
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut Union de ceux qui n'ont jamais eu de CDD et ceux qui en ont eu.
    Bonjour,

    Soit une table contrat contenant, entre autre, les colonnes suivantes :
    - no_dossier_pers : numéro de dossier de la personne (en fait l'identifiant de l'individu) ;
    - d_fin_contrat_trav : la date de fin du contrat de travail.

    Les contrats en CDD ont une date de fin, les CDI bien sûr n'en ont pas (colonne à NULL... oui, je sais, c'est mal mais ce n'est pas moi qui ai conçu ça ! ).

    Certaines personnes ont eu un ou plusieurs CDD puis un CDI. Il existe donc, pour ces personnes, au moins une ligne avec une date de fin non nulle et une avec une date de fin nulle.
    D'autres personnes n'ont eu que un ou plusieurs CDD et ont donc une ou des lignes avec toujours une date de fin non nulle.

    J'ai besoin de savoir pour chaque personne :
    - quelle est la date de fin maxi s'il n'y a pas eu de CDI ensuite ;
    - NULL si la personne est finalement en CDI.

    Voilà la requête que j'ai pondue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    -- Ceux qui n'ont pas de contrat avec une date de fin non nulle
    SELECT DISTINCT c.no_dossier_pers, NULL AS dern_fin_contrat
    FROM mangue.contrat c
    WHERE NOT EXISTS
    (
    	SELECT *
    	FROM mangue.contrat c2
    	WHERE c2.no_dossier_pers = c.no_dossier_pers
    		AND c2.D_FIN_CONTRAT_TRAV IS NOT NULL
    )
    UNION
    -- Ceux qui ont au moins un contrat avec une date de fin non nulle
    SELECT cnn.no_dossier_pers,
    	CASE
    		WHEN cn.no_dossier_pers IS NULL THEN cnn.dern_fin_contrat
    		ELSE NULL
    	END AS dern_fin_contrat
    FROM
    (
    	SELECT no_dossier_pers,
    		MAX(D_FIN_CONTRAT_TRAV) AS dern_fin_contrat
    	FROM mangue.contrat
    	WHERE D_FIN_CONTRAT_TRAV IS NOT NULL
    	GROUP BY no_dossier_pers
    ) cnn
    LEFT JOIN
    (
    	SELECT DISTINCT no_dossier_pers
    	FROM mangue.contrat
    	WHERE D_FIN_CONTRAT_TRAV IS NULL
    ) cn ON cn.no_dossier_pers = cnn.no_dossier_pers
    ORDER BY no_dossier_pers
    Comme ceci sera dans une plus grosse requête, y a t-il plus simple ?

    Merci de vos avis.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    je ne suis pas sûr d'avoir saisi toutes les subtilités du besoin.

    Est-ce que ceci y répond ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT 
    		no_dossier_pers
    	,	CASE 
    		WHEN MAX(CASE WHEN D_FIN_CONTRAT_TRAV IS NULL THEN 1 ELSE 0 END) = 1 
    			THEN NULL 
    			ELSE MAX(D_FIN_CONTRAT_TRAV) 
    		END AS dern_fin_contrat
    FROM	contrat 
    GROUP BY no_dossier_pers
    ;
    avec une alternative moins élégante mais plus condensée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT 
      no_dossier_pers
       ,NULLIF(MAX(COALESCE(D_FIN_CONTRAT_TRAV,TO_DATE('99991231','YYYYMMDD'))),TO_DATE('99991231','YYYYMMDD'))
    FROM contrat
    GROUP BY no_dossier_pers
    ;

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Merci aieeeuuuuu.

    Je conserve ta première solution qui fonctionne très bien.

    Dans la seconde, je ne comprends pas le sens de TO_DATE('99991231','YYYYMMDD') ni pourquoi il est répété deux fois.

    En plus, je préfère le SQL standard donc la première solution.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Utilisez First/Last
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Select no_dossier_pers, 
           Max(d_fin_contrat_trav) Keep (Dense_Rank Last Order By d_fin_contrat_trav)
      From Data
     Group By no_dossier_pers 
    /

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    J'ai également une préférence pour la première solution !

    pour le TO_DATE('99991231','YYYYMMDD'), l'idée est de remplacer les dates NULL par cette date, afin qu'elle ressorte avec le MAX. le deuxième TO_DATE('99991231','YYYYMMDD') est en deuxième argument du NULLIF afin de remettre à NULL au lieu de garder cette valeur qui n'a pas de sens en dehors de la requête (et comme je sais que tu aimes les NULL... )

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    C'est encore plus concis et ça fonctionne ; merci mnitu.

    D'après l'explication donnée ici, ta requête ordonne les d_fin_contrat_trav pour un no_dossier_pers et conserve la dernière d_fin_contrat_trav.

    Ce à quoi je n'avais pas pensé, c'est que NULL est classé après toutes les dates chez Oracle. Sous MySQL, c'est le contraire ; les NULL sont placés avant suite à un ORDER BY.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Ce à quoi je n'avais pas pensé, c'est que NULL est classé après toutes les dates chez Oracle. Sous MySQL, c'est le contraire ; les NULL sont placés avant suite à un ORDER BY.
    En l'occurence, on peut préciser pour avoir les nulls en premier ou en dernier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by toto NULLS first/last

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    OK pour Oracle mais KO pour MySQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM `calendrier` order by date_heure_locale nulls last
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'nulls last
    Ceci dit, dans le cas présent, je m'en fous puisque mon problème concernait Oracle.

    Merci à tous.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Par contre si après un CDI (date fin du contrat à Null) la personne donne sa démission mais revient un an plus tard en CDD et qu'il garde son numéro du dossier, la requête renvoie un mauvais résultat.

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Je n'ai pas connaissance de tels cas. Par contre, il y a aussi des gens qui ont commencé comme contractuels (CDD puis éventuellement CDI) puis sont devenus fonctionnaires. Ça va être ma difficulté suivante parce que les fonctionnaires sont gérés dans d'autres tables. Il est donc fort probable que j'ouvre un autre sujet.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Par contre si après un CDI (date fin du contrat à Null) la personne donne sa démission mais revient un an plus tard en CDD et qu'il garde son numéro du dossier, la requête renvoie un mauvais résultat.
    Dans ce cas, il paraitrait logique de renseigner la date de fin de contrat (CDI) lors de la démission qui, en soit, constitue bien une fin de contrat.

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 793
    Points : 34 024
    Points
    34 024
    Billets dans le blog
    14
    Par défaut
    Bon finalement je ne vais sans doute pas avoir besoin de tout ça.

    Merci quand même ; j'ai appris des trucs que j'espère ne pas oublier trop vite.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  13. #13
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    [...]je ne comprends pas le sens de TO_DATE('99991231','YYYYMMDD') ni pourquoi il est répété deux fois.

    En plus, je préfère le SQL standard [...]
    Il suffit de l'écrire comme ça et ça devient du beau SQL normatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      select no_dossier_pers
           , nullif(max(coalesce(d_fin_contrat_trav, date '9999-12-31')), date '9999-12-31')
        from contrat
    group by no_dossier_pers;
    Ce qui est intéressant avec la requête de mnitu, c'est qu'elle montre que finalement le problème de départ :
    Citation Envoyé par CinePhil
    J'ai besoin de savoir pour chaque personne :
    - quelle est la date de fin maxi s'il n'y a pas eu de CDI ensuite ;
    - NULL si la personne est finalement en CDI.
    Se synthétise très bien en : "quelle est la date de fin du dernier contrat ?".
    Et je suis certain que tu sais écrire cette requête !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requete qui n'ont JAMAIS
    Par baobab95 dans le forum SQL
    Réponses: 6
    Dernier message: 19/11/2010, 12h35
  2. [MATERIEL] Batterie qui gonfle ? non jamais :D
    Par netah25 dans le forum Apple
    Réponses: 1
    Dernier message: 03/04/2008, 13h31
  3. Text Defilant qui se cache jamais o_O
    Par snipes dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 03/06/2007, 05h40
  4. Réponses: 2
    Dernier message: 10/01/2007, 14h33
  5. [csv]import qui ne termine jamais
    Par banzzai dans le forum Requêtes
    Réponses: 6
    Dernier message: 14/06/2006, 22h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo