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

PostgreSQL Discussion :

Besoin d'une fonction pour trouver des éléments identiques dans une table


Sujet :

PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut Besoin d'une fonction pour trouver des éléments identiques dans une table
    Soit une table contenant un champs nolot, un champ nom et un champs prenom. J'ai besoin, en entrant un nolot en argument de la fonction, quels sont tous les lots ayant toutes les mêmes valeurs pour nom et prénom.

    Je pense qu'un exemple serait utile.

    Soit la table

    nolot | prénom | nom
    ---------------------
    4000 | Albert | Einstein
    4000 | Mileva | Einstein
    4001 | Marie | Curie
    4001 | Pierre | Curie
    4002 | Albert | Einstein
    4003 | Barack | Obama
    4004 | Albert | Einstein
    4004 | Mileva |Einstein
    J'ai besoin de sortir, pour formule(4000) la liste suivante

    nolot
    -----
    4000
    4004
    4004 doit sortir parce qu'il contient Albert Einstein ET Mileva Einstein, tout comme 4000 qui est en argument de la formule.
    4002 ne devra pas sortir parce qu'il ne contient pas Mileva Einstein.

    Je n'ai pas encore fais assez de formules pour PostgreSQL pour réussir à faire celle là, mais j'en ai besoin.
    Je sêche, aussi je fais appel à vous.

    Merci de vos z'avis z'avisés,
    Jean-Marc

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Il s'agit d'un cas de division relationnelle assez classique. Lisez l'article que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/divrelationnelle/

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    bonjour et merci de ce tuto exemplaire.

    Je sêche toutefois encore. Je suis dans le dernier cas : le cas de la division exacte.
    Je n'arrive pas à ramener tout cela à une seule table source.
    Dans votre exemple d'appareils, admettons qu'il faille sortir tous les appareils contenant les mêmes composants, ni plus, ni moins, et que, de plus, un composant pourrait se retrouver plusieurs fois.
    Pour se ramener à mon cas, il se peut qu'un lot ait 2 Albert Einstein (car il y a des lots ou des personnes différentes portent le même nom et prénom) et une Milesa Einstein. Il faudrait donc trouver tous les lots contenant 2 Albert Einstein et 1 Milesa Einstein, tout en sachant aussi que le nom et le prénom sont dans des champs séparés. Je ne sais pas si, pour simplifier, il serait bon de concaténer le nom et le prénom ou si cela, dans certains cas, pourrait nous induire en erreur.
    En fait, il me faut trouver tous les lots ayant toutes les mêmes personnes que le lot dont le numéro est entré en argument dans la fonction.

    Merci toutefois de l'attention que vous portez à ma recherche,

    JM

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Il y a une solution relativement simple en passant par des tableaux intermédiaires. Simple mais peu performante, à voir en fonction des volumes si c'est un problème ou pas.

    L'idée est de placer dans un tableau dynamique tous les couples nom-prénom correspondant à chaque lot particulier, par une requête du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT nolot, array_agg(row(prenom, nom)) AS liste FROM lot GROUP BY nolot
    A combiner avec l'opérateur d'égalité des tableaux pour trouver n'importe quel lot qui a exactement le même contenu qu'un autre lot, par exemple pour le 4000:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select nolot from 
      (select nolot, array_agg(row(prenom, nom)) AS liste from lot group by nolot) s1
     where liste=(select array_agg(row(prenom, nom)) from lot where nolot=4000);
    La fonction array_agg est dispo en standard à partir de PG 8.4 seulement, mais si version antérieure il suffit de la créer, voir l'exemple de array_accum dans la documentation.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Visiblement mes articles ne vous ont pas inspiré. Pour autant la solution y figure bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE JeanMarc68 
    (nolot int, prenom varchar(8), nom varchar(8));
     
    INSERT INTO JeanMarc68 VALUES (4000, 'Albert', 'Einstein');
    INSERT INTO JeanMarc68 VALUES (4000, 'Mileva', 'Einstein');
    INSERT INTO JeanMarc68 VALUES (4001, 'Marie',  'Curie');
    INSERT INTO JeanMarc68 VALUES (4001, 'Pierre', 'Curie');
    INSERT INTO JeanMarc68 VALUES (4002, 'Albert', 'Einstein');
    INSERT INTO JeanMarc68 VALUES (4003, 'Barack', 'Obama');
    INSERT INTO JeanMarc68 VALUES (4004, 'Albert', 'Einstein');
    INSERT INTO JeanMarc68 VALUES (4004, 'Mileva', 'Einstein ');
    -- solution
    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
    WITH T AS
    (SELECT nom, prenom
     FROM   JeanMarc68
     INTERSECT
     SELECT nom, prenom
     FROM   JeanMarc68
     WHERE  nolot = 4000)
    SELECT nolot
    FROM   JeanMarc68 AS JM
           INNER JOIN T
                 ON JM.nom = T.nom
                    AND JM.prenom = T.prenom
    GROUP BY nolot                
    HAVING COUNT(*) = (SELECT COUNT(*)
                       FROM   T)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    nolot
    -----------
    4000
    4004
    Et si vous voulez apprendre le SQL, mon site, comme mes bouquins, peuvent vous y aider !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    La requête que tu proposes ne convient pas à cause de la contrainte qui est mentionnée sur les doublons de prénom et nom:
    Pour se ramener à mon cas, il se peut qu'un lot ait 2 Albert Einstein (car il y a des lots ou des personnes différentes portent le même nom et prénom) et une Milesa Einstein. Il faudrait donc trouver tous les lots contenant 2 Albert Einstein et 1 Milesa

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

Discussions similaires

  1. Créer une fonction pour ajouter des clés/valeurs dans ma hashmap
    Par khalous91 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 05/05/2015, 13h40
  2. [Débutant] Calcul précis de la dérivée d'une fonction pour trouver des pics
    Par abel413 dans le forum MATLAB
    Réponses: 3
    Dernier message: 25/07/2013, 11h24
  3. Réponses: 4
    Dernier message: 01/06/2007, 19h15
  4. Réponses: 8
    Dernier message: 11/04/2007, 23h06
  5. Réponses: 1
    Dernier message: 10/09/2006, 16h09

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