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

Requêtes MySQL Discussion :

Nom des amis commun entre deux utilisateurs


Sujet :

Requêtes MySQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut Nom des amis commun entre deux utilisateurs
    Bonjour,

    j'ai deux tables.

    users:

    id
    nom
    prenom
    email
    password

    friends:

    id_invitation
    id_exp
    id_des
    valide
    date_invitation
    date_activation

    Je veux recuperer le nom des amis communs entre deux utilisateurs.
    Par example:
    1,2,3 sont tous amis entre eux, c'est à dire:
    1 est ami avec 2 et 3; 2 aussi est ami avec 3
    Je veux recuperer 3 comme ami commun entre 1 et 2. (sachant que l'invitation peut provenir de 1 vers 2 ou de 2 vers 1).

    Ce code ne contrôle qu'UNE direction. Où les deux ont invité le même ami, alors que je veux une invitation circulaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT f.id_des, u.nom
    FROM friends f
    LEFT JOIN users u ON u.id=f.id_des
    WHERE 
    f.id_exp=$f2_id AND
    f.id_des IN (
    SELECT id_des
    FROM friends
    WHERE id_exp=$f1_id
    )
    MercI,

  2. #2
    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
    1) Ne nommez pas vos tables au pluriel et évitez les noms pouvant être interprétés comme des mots du langage SQL.

    2) Liste des users avec tous leurs amis invités.
    L'invitation n'est pas suffisante mais qu'il faut que valide soit à TRUE pour que les deux users soient amis, ajoutez une condition de restriction à ma requête (clause WHERE).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT u.id AS id_invitant, 
    	f.id_des AS id_ami
    FROM users u
    INNER JOIN friends f ON f.id_exp = u.id
    3) Pour chaque user, quels sont les amis de ses amis ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f.id_exp = u.id -- amis du user
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp -- amis de l'ami du user
    4) Amis communs de chaque user :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f.id_exp = u.id -- amis du user
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp -- amis de l'ami du user
    WHERE f2.id_des <> u.id -- L'ami de l'ami n'est pas le user
    	AND f2.id_des = f1.id_des -- L'ami de l'ami est l'ami du user
    À tester...
    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 !

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    Bonsoir et merci pour ta disponibilité;
    mais oû je pourrais placer les variables parce qu'il faut renseigner deux variables(je veux parler des deux utilisateur dont on cherche les amis communs, dans ce cas l'ami commun entre 1 et 2).
    Je vois pas oû renseigner les variables.
    Merci.

  4. #4
    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
    Ben dans le WHERE !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f.id_exp = u.id -- amis du user
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp -- amis de l'ami du user
    WHERE f2.id_des <> u.id -- L'ami de l'ami n'est pas le user
    	AND f2.id_des = f1.id_des -- L'ami de l'ami est l'ami du user
    	AND u.id = 1
    	AND f1.id_des = 2
    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 !

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut Erreur phpmyadmin
    J'ai testé celà:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f.id_exp = u.id 
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp 
    WHERE 
    	( f2.id_des = f1.id_des 
    	AND u.id = 445
    	AND f1.id_des = 368 )
    Et phpmyadmin dans WAMP me montre cette erreur:

    Erreur
    Requête SQL : Documentation


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f.id_exp = u.id 
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp 
    WHERE 
    	( f2.id_des = f1.id_des 
    	AND u.id = 1
    	AND f1.id_des = 2) LIMIT 0, 25
    MySQL a répondu:

    #1054 - Champ 'f.id_exp' inconnu dans on clause

  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
    Je n'ai fait que reprendre le nom de vos colonnes de votre premier message :
    j'ai deux tables.

    users:

    id
    nom
    prenom
    email
    password

    friends:

    id_invitation
    id_exp
    id_des
    valide
    date_invitation
    date_activation
    Vérifiez le nom de vos colonnes dans votre table réelle.

    EDIT : c'est f1.id_exp et non pas f.id_exp !
    C'est l'alias f qui n'est pas bon
    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
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    J' ai essayé ce code!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT u.id AS id_invitant, 
    	f1.id_des AS id_ami,
    	f2.id_des AS id_ami_de_l_ami
    FROM users u
    INNER JOIN friends f1 ON f1.id_exp = u.id -- amis du user
    	INNER JOIN friends f2 ON f2.id_exp = f1.id_exp -- amis de l'ami du user
    WHERE 
    	 f2.id_des = f1.id_des -- L'ami de l'ami est l'ami du user
    	AND u.id = 368
    	AND f1.id_des = 400


    ça me donne:

    Nom : Capture4.PNG
Affichages : 379
Taille : 27,9 Ko


    Voila le contenu de ma table friends:


    Nom : Capture2.PNG
Affichages : 415
Taille : 18,4 Ko

    Regarde les trois dernieres lignes.

    Il devrait me retourner "445"
    Le code ne fonctionne pas, il donne autre chose on dirait ?

  8. #8
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut mohamed lamine 1996.

    Je réponds au premier message !
    Ce qui me dérange dans votre définition de l'amitié est la non réciprocité.
    Autrement dit, si "1" est amis avec "2", parce qu'il en a fait la demande, alors "2" ne sera pas amis avec "1", car la demande est absente.

    Pour résoudre le problème de la réciprocité, il faut tester deux cas, soit exp-->des et des-->exp.
    Autrement dit, vous devrez faire un "union" !

    Et en ce qui concerne votre demande d'origine, vous devez rechercher pour un destinataire donné, plus de un émetteur (>1).
    Ce qui donne :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `user`
    --------------
     
    --------------
    CREATE TABLE `user`
    ( `id`        integer unsigned  not null auto_increment primary key,
      `nom`       varchar(255)      not null,
      `prenom`    varchar(255)      not null,
      `email`     varchar(255)      not null,
      `password`  varchar(255)      not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `user` (`nom`,`prenom`,`email`,`password`) values
      ('nom 1','prénom 1','prenom1.nom1@email.com','password1'),
      ('nom 2','prénom 2','prenom2.nom2@email.com','password2'),
      ('nom 3','prénom 3','prenom3.nom3@email.com','password3'),
      ('nom 4','prénom 4','prenom4.nom4@email.com','password4'),
      ('nom 5','prénom 5','prenom5.nom5@email.com','password5')
    --------------
     
    --------------
    select * from `user`
    --------------
     
    +----+-------+----------+------------------------+-----------+
    | id | nom   | prenom   | email                  | password  |
    +----+-------+----------+------------------------+-----------+
    |  1 | nom 1 | prénom 1 | prenom1.nom1@email.com | password1 |
    |  2 | nom 2 | prénom 2 | prenom2.nom2@email.com | password2 |
    |  3 | nom 3 | prénom 3 | prenom3.nom3@email.com | password3 |
    |  4 | nom 4 | prénom 4 | prenom4.nom4@email.com | password4 |
    |  5 | nom 5 | prénom 5 | prenom5.nom5@email.com | password5 |
    +----+-------+----------+------------------------+-----------+
    --------------
    DROP TABLE IF EXISTS `friend`
    --------------
     
    --------------
    CREATE TABLE `friend`
    ( `id_invitation`        integer unsigned  not null auto_increment primary key,
      `id_exp`               integer unsigned  not null,
      `id_des`               integer unsigned  not null,
      `valide`               char(01)          not null,
      `date_invitation`      date              not null,
      `date_activation`      date              not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `friend` (`id_exp`,`id_des`,`valide`,`date_invitation`,`date_activation`) values
      ( 1,  2, 'y', '2017-09-01', '2017-09-01'),
      ( 1,  3, 'y', '2017-09-01', '2017-09-01'),
      ( 2,  3, 'y', '2017-09-01', '2017-09-01'),
     
      ( 4,  5, 'y', '2017-09-01', '2017-09-01'),
      ( 5,  6, 'y', '2017-09-01', '2017-09-01'),
      ( 6,  4, 'y', '2017-09-01', '2017-09-01')
    --------------
     
    --------------
    select * from `friend`
    --------------
     
    +---------------+--------+--------+--------+-----------------+-----------------+
    | id_invitation | id_exp | id_des | valide | date_invitation | date_activation |
    +---------------+--------+--------+--------+-----------------+-----------------+
    |             1 |      1 |      2 | y      | 2017-09-01      | 2017-09-01      |
    |             2 |      1 |      3 | y      | 2017-09-01      | 2017-09-01      |
    |             3 |      2 |      3 | y      | 2017-09-01      | 2017-09-01      |
    |             4 |      4 |      5 | y      | 2017-09-01      | 2017-09-01      |
    |             5 |      5 |      6 | y      | 2017-09-01      | 2017-09-01      |
    |             6 |      6 |      4 | y      | 2017-09-01      | 2017-09-01      |
    +---------------+--------+--------+--------+-----------------+-----------------+
    --------------
    select      u.nom,
                u.prenom,
                f.des,
                f.exp
          from  (  select  id_des               as des,
                           group_concat(id_exp) as exp,
                           count(*) as nbre
                     from  `friend`
                 group by  id_des
                   having  nbre > 1
                    union
                   select  id_exp               as des,
                           group_concat(id_des) as exp,
                           count(*) as nbre
                     from  `friend`
                 group by  id_exp
                   having  nbre > 1) as f
     
    inner join  `user` as u
            on  u.id = f.des
    --------------
     
    +-------+----------+-----+------+
    | nom   | prenom   | des | exp  |
    +-------+----------+-----+------+
    | nom 1 | prénom 1 |   1 | 2,3  |
    | nom 3 | prénom 3 |   3 | 1,2  |
    +-------+----------+-----+------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    Selon la formulation de votre exemple, on constate que 1 et 3 ont au moins 2 amis.

    Oui, sauf que cette méthode ne sait pas résoudre une forme circulaire : 1-->2, 2-->3 et 3-->1.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    Où je pourrai renseigner les deux variables dont je cherche les amis commun ?
    Merci

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut mohamed lamine 1996.

    Votre demande concerne uniquement les expéditeurs. Cela va se traduire par ce que j'ai mis en rouge :
    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
    --------------
    select      u.nom,
                u.prenom,
                f.des,
                f.exp
          from  (  select  id_des               as des,
                           group_concat(id_exp) as exp,
                           count(*) as nbre
                     from  `friend`
                    where  id_exp in (1, 2)
                 group by  id_des
                   having  nbre > 1) as f
    
    inner join  `user` as u
            on  u.id = f.des
    --------------
    
    +-------+----------+-----+------+
    | nom   | prenom   | des | exp  |
    +-------+----------+-----+------+
    | nom 3 | prénom 3 |   3 | 1,2  |
    +-------+----------+-----+------+
    --------------
    COMMIT
    
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    Ma demande ne concerne pas que les expéditeurs, mais des récepteurs aussi.

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par mohamed lamine 1996 Voir le message

    1,2,3 sont tous amis entre eux, c'est à dire:
    1 est ami avec 2 et 3; 2 aussi est ami avec 3
    Je veux recuperer 3 comme ami commun entre 1 et 2. (sachant que l'invitation peut provenir de 1 vers 2 ou de 2 vers 1).

    Ce code ne contrôle qu'UNE direction. Où les deux ont invité le même ami, alors que je veux une invitation circulaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT f.id_des, u.nom
    FROM friends f
    LEFT JOIN users u ON u.id=f.id_des
    WHERE 
    f.id_exp=$f2_id AND
    f.id_des IN (
    SELECT id_des
    FROM friends
    WHERE id_exp=$f1_id
    )
    C'est une invitation circulaire que je veux; en d'autres termes je veux une réciprocité pas dans un seul sens et je l'ai bien indiqué dans mon premier post(regarde au tout debut)
    Merci.

  13. #13
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 736
    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 736
    Points : 52 447
    Points
    52 447
    Billets dans le blog
    5
    Par défaut
    Avec les tables suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE T_USR
    (USR_ID                INT PRIMARY KEY,
     USR_NOM               CHAR(32),
     USR_PRENOM            VARCHAR(25),
     USR_EMAIL             VARCHAR(256),
     USR_PASSWORD          CHAR(16));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE T_IVT
    (IVT_ID                INT PRIMARY KEY,
     USR_ID_EXP            INT REFERENCES T_USR (USR_ID),
     USR_ID_DES            INT REFERENCES T_USR (USR_ID),
     IVT_VALIDE            BIT,
     IVT_DATE_INVITATION   DATE,
     IVT_DATE_ACTIVATION   DATE);
    Mes deux utilisateurs s’appellent Jean et Luc... jean ayant l'ID 123, luc ayant l'id 987

    première solution avec l'opérateur ensembliste INTERSECT :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- les amis de jean (jean ayant l'ID 123)
    SELECT AMI.USR_ID, AMI.USR_NOM, AMI.USR_PRENOM
    FROM   T_USR AS JEAN
           JOIN T_IVT AS I ON JEAN.USR_ID = I.USR_ID_EXP
    	   JOIN T_USR AS AMI ON I.USR_ID_DES = AMI.USR_ID
    WHERE  JEAN.USR_ID = 123
    INTERSECT --> ne trouve que les lignes communes aux 2 requêtes
    -- les amis de LUC (luc ayant l'id 987)
    SELECT AMI.USR_ID, AMI.USR_NOM, AMI.USR_PRENOM
    FROM   T_USR AS LUC
           JOIN T_IVT AS I ON LUC.USR_ID = I.USR_ID_EXP
    	   JOIN T_USR AS AMI ON I.USR_ID_DES = AMI.USR_ID
    WHERE  LUC.USR_ID = 987;
    Seconde solution à base de jointures
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT AMI_JEAN.USR_ID, AMI_JEAN.USR_NOM, AMI_JEAN.USR_PRENOM
    FROM   T_USR AS JEAN
           JOIN T_IVT AS IJ ON JEAN.USR_ID = IJ.USR_ID_EXP
    	   JOIN T_USR AS AMI_JEAN ON IJ.USR_ID_DES = AMI_JEAN.USR_ID
    	   JOIN T_USR AS AMI_LUC ON AMI_JEAN.USR_ID = AMI_LUC.USR_ID
    	   JOIN T_IVT AS IL ON AMI_LUC.USR_ID = IL.USR_ID_DES
    	   JOIN T_USR AS LUC ON IL.USR_ID_EXP = LUC.USR_ID
    WHERE  JEAN.USR_ID = 123 AND LUC.USR_ID = 987;
    On rajoutera si besoin est les restrictions sur IVT_VALIDE et/ou IVT_DATE_INVITATION/IVT_DATE_ACTIVATION dans la clause WHERE

    Il existe quantité d'autres écritures avec des sous requêtes....

    Et pour vous former à SQL, mon livre comme mon site peuvent vous y aider
    Nom : Couverture SQL Synthex 4e ed - 500.jpg
Affichages : 336
Taille : 77,8 Ko


    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/ * * * * *

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut mohamed lamine 1996.

    Le problème n'est pas aussi simple qu'il y parait au premier abord, car cela dépend comment les lignes ont été insérés dans la table.
    D'une part, comme la réciprocité n'a pas été traitée dans le remplissage de la table, de ce fait, pour vérifier que la requête fonctionne correctement, j'ai dû faire un jeu d'essai qui dénombre les huit cas que nous obtenons avec trois amis.
    a) 1 --> 2, 1--> 3, 2 --> 3
    b) 1 --> 2, 1--> 3, 3 --> 2

    c) 1 --> 2, 3--> 1, 2 --> 3
    d) 1 --> 2, 3--> 1, 3 --> 2

    e) 2 --> 1, 1--> 3, 2 --> 3
    f) 2 --> 1, 1--> 3, 3 --> 2

    g) 2 --> 1, 3--> 1, 2 --> 3
    h) 2 --> 1, 3--> 1, 3 --> 2

    Si la réciprocité avait été traité dans la table, la solution que je propose dans mon message #10 serait bien plus simple à mettre en oeuvre.

    D'autre part, MySql ne sait pas traiter, à l'inverse de Microsoft SQL Server, l'intersection, nous devons donc la simuler.
    Comment ai-je procédé ?

    Dans un premier temps, je récupère soit l'expéditeur soit le destinataire que je baptise 'val', autre que celui où l'utilisateur est '1'.
    Dans un second temps, je récupère soit l'expéditeur soit le destinataire que je baptise 'val', autre que celui où l'utilisateur est '2'.
    Je cherche ce qui est commun entre la première extraction et la seconde extraction.
    Puis enfin, je fais le lien avec la table des 'user'. Voici ce que cela donne :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `user`
    --------------
     
    --------------
    CREATE TABLE `user`
    ( `id`        integer unsigned  not null auto_increment primary key,
      `nom`       varchar(255)      not null,
      `prenom`    varchar(255)      not null,
      `email`     varchar(255)      not null,
      `password`  varchar(255)      not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `user` (`nom`,`prenom`,`email`,`password`) values
      ('nom 1','prénom 1','prenom1.nom1@email.com','password1'),
      ('nom 2','prénom 2','prenom2.nom2@email.com','password2'),
      ('nom 3','prénom 3','prenom3.nom3@email.com','password3')
    --------------
     
    --------------
    select * from `user`
    --------------
     
    +----+-------+----------+------------------------+-----------+
    | id | nom   | prenom   | email                  | password  |
    +----+-------+----------+------------------------+-----------+
    |  1 | nom 1 | prénom 1 | prenom1.nom1@email.com | password1 |
    |  2 | nom 2 | prénom 2 | prenom2.nom2@email.com | password2 |
    |  3 | nom 3 | prénom 3 | prenom3.nom3@email.com | password3 |
    +----+-------+----------+------------------------+-----------+
    --------------
    DROP TABLE IF EXISTS `friend`
    --------------
     
    --------------
    CREATE TABLE `friend`
    ( `id`       integer unsigned  not null auto_increment primary key,
      `cas`      char(01)          not null,
      `id_exp`   integer unsigned  not null,
      `id_des`   integer unsigned  not null,
      CONSTRAINT `fk_exp` FOREIGN KEY (`id_exp`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
      CONSTRAINT `fk_des` FOREIGN KEY (`id_des`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `friend` (`cas`, `id_exp`,`id_des`) values
      ('a', 1, 2), ('a', 1, 3), ('a', 2, 3),
      ('b', 1, 2), ('b', 1, 3), ('b', 3, 2),
      ('c', 1, 2), ('c', 3, 1), ('c', 2, 3),
      ('d', 1, 2), ('d', 3, 1), ('d', 3, 2),
      ('e', 2, 1), ('e', 1, 3), ('e', 2, 3),
      ('f', 2, 1), ('f', 1, 3), ('f', 3, 2),
      ('g', 2, 1), ('g', 3, 1), ('g', 2, 3),
      ('h', 2, 1), ('h', 3, 1), ('h', 3, 2)
    --------------
     
    --------------
    select * from `friend`
    --------------
     
    +----+-----+--------+--------+
    | id | cas | id_exp | id_des |
    +----+-----+--------+--------+
    |  1 | a   |      1 |      2 |
    |  2 | a   |      1 |      3 |
    |  3 | a   |      2 |      3 |
    |  4 | b   |      1 |      2 |
    |  5 | b   |      1 |      3 |
    |  6 | b   |      3 |      2 |
    |  7 | c   |      1 |      2 |
    |  8 | c   |      3 |      1 |
    |  9 | c   |      2 |      3 |
    | 10 | d   |      1 |      2 |
    | 11 | d   |      3 |      1 |
    | 12 | d   |      3 |      2 |
    | 13 | e   |      2 |      1 |
    | 14 | e   |      1 |      3 |
    | 15 | e   |      2 |      3 |
    | 16 | f   |      2 |      1 |
    | 17 | f   |      1 |      3 |
    | 18 | f   |      3 |      2 |
    | 19 | g   |      2 |      1 |
    | 20 | g   |      3 |      1 |
    | 21 | g   |      2 |      3 |
    | 22 | h   |      2 |      1 |
    | 23 | h   |      3 |      1 |
    | 24 | h   |      3 |      2 |
    +----+-----+--------+--------+
    --------------
    select      x.cas,
                x.val,
                u.nom,
                u.prenom
     
          from  (  select  cas,
                           id_des as val
                     from  `friend`
                    where  id_exp = 1
                    union
                   select  cas,
                           id_exp as val
                     from  `friend`
                    where  id_des = 1
                )    as x
     
    inner join  (  select  cas,
                           id_des as val
                     from  `friend`
                    where  id_exp = 2
                    union
                   select  cas,
                           id_exp as val
                     from  `friend`
                    where  id_des = 2
                )    as y
     
    inner join  user as u
            on  u.id = x.val
     
         where  x.cas = y.cas
           and  x.val = y.val
     
      order by  x.cas
    --------------
     
    +-----+-----+-------+----------+
    | cas | val | nom   | prenom   |
    +-----+-----+-------+----------+
    | a   |   3 | nom 3 | prénom 3 |
    | b   |   3 | nom 3 | prénom 3 |
    | c   |   3 | nom 3 | prénom 3 |
    | d   |   3 | nom 3 | prénom 3 |
    | e   |   3 | nom 3 | prénom 3 |
    | f   |   3 | nom 3 | prénom 3 |
    | g   |   3 | nom 3 | prénom 3 |
    | h   |   3 | nom 3 | prénom 3 |
    +-----+-----+-------+----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    La solution semble compliquée mais elle permet de simuler l'intersection entre deux ensembles de données.

    J'ai introduit la colonne "cas" pour distinguer toutes les solutions possibles que nous pouvons avoir avec l'amitié sans la réciprocité.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 45
    Points : 36
    Points
    36
    Par défaut
    @Artemus24 Si je pouvais résoudre ce problème (apparemment insolvable) sans modifier les tables serait très très génial.
    En effet, je ne peux pas me permettre de modifier les tables ou l'une des tables pour ne pas risquer de causer d'autres erreurs à d'autres parties du code( j'ai déjà plus de 5000 lignes de codes et les tables sont très utilisées, il faut donc être très prudent pour y modifier quoi que ce soit).
    Je préférerais laisser tomber si je trouve pas de solution au lieu de modifier les tables.

    MERCI quand même pour toutes vos aides précieuses et je suis toujours dans l'attente d'un sauveur miracle.

  16. #16
    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
    Reprenons depuis le début...

    Dans un premier temps, je fais abstraction de la table users qui ne sert qu'à récupérer les informations des users et je me concentre sur la table friends
    friends:

    id_invitation
    id_exp
    id_des
    valide
    date_invitation
    date_activation
    Par exemple:
    1,2,3 sont tous amis entre eux, c'est à dire:
    1 est ami avec 2 et 3; 2 aussi est ami avec 3
    Je veux récupérer 3 comme ami commun entre 1 et 2. (sachant que l'invitation peut provenir de 1 vers 2 ou de 2 vers 1).
    Je comprends de ceci que la table friends contient les lignes suivantes (en faisant abstraction des dates qui ne nous servent à rien) :
    id_invitation, id_exp, id_des, valide
    1, 1, 2, 1
    2, 1, 3, 1
    3, 2, 3, 1

    J'ajoute des lignes qui ne devront pas être retournées par la requête finale :
    4, 1, 4, 1
    5, 2, 4, 0
    6, 2, 5, 1
    7, 1, 6, 1
    8, 5, 1, 1

    1) Quel sont les amis validés de 1 et 2 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id_exp, id_des
    FROM friends
    WHERE id_exp IN(1, 2);
    => Cette requête devrait donner ceci :
    id_exp, id_des
    1, 2
    1, 3
    1, 4
    1, 6
    2, 3
    2, 5


    2) Quels sont les amis communs à 1 et 2 ?
    => Les id_des qui sont présents plus d'une fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT id_des
    FROM friends
    WHERE id_exp IN(1, 2)
    	AND valide = 1
    GROUP BY id_des
    HAVING COUNT(*) = 2 -- Nombre d'éléments dans la clause IN
    => Cette requête devrait donner 3 en résultat puisque c'est le seul id_des en double dans le résultat précédent.

    Mais...
    [QUOTE(sachant que l'invitation peut provenir de 1 vers 2 ou de 2 vers 1)[/QUOTE]
    Donc, si je comprends bien, avec mes données, on devrait aussi obtenir 5 puisque selon l'id_invitation 6, 2 est ami avec 5 et selon l'id_invitation 8, 5 est ami avec 1. Donc 1 est ami avec 5 et 5 est bien un ami commun à 1 et 2.

    3) Faisons l'union des invitations de 1 et 2 avec les invitations vers 1 et 2, de façon à n'avoir que 1 et 2 dans la première colonne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT id_exp, id_des
    FROM friends
    WHERE id_exp IN(1, 2)
    	AND valide = 1
    UNION
    SELECT id_des, id_exp
    FROM friends
    WHERE id_des IN(1,2)
    	AND valide = 1
    => Cette requête devrait donner ceci :
    id_exp, id_des
    1, 2
    1, 3
    1, 4
    1, 6
    2, 3
    2, 5
    2, 1
    1, 5

    => 5 apparait deux fois donc est un ami commun à 1 et 2.

    4) Extrayons les id_des apparaissant deux fois pour obtenir notre résultat final :
    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
    SELECT id_des
    FROM
    (
    	SELECT id_exp, id_des
    	FROM friends
    	WHERE id_exp IN(1, 2)
    		AND valide = 1
    	UNION
    	SELECT id_des, id_exp
    	FROM friends
    	WHERE id_des IN(1,2)
    		AND valide = 1
    ) tmp
    GROUP BY id_des
    HAVING COUNT(*) = 2 -- Nombre d'éléments dans les clauses IN
    À tester avec vos données.

    5) Si vous voulez récupérer les informations de ces amis communs, il suffit de faire une jointure avec la table users :
    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
    SELECT u.id as id_ami_commun,
    	u.nom, u.prenom
    FROM users u
    (
    	SELECT id_exp, id_des
    	FROM friends
    	WHERE id_exp IN(1, 2)
    		AND valide = 1
    	UNION
    	SELECT id_des, id_exp
    	FROM friends
    	WHERE id_des IN(1,2)
    		AND valide = 1
    ) tmp ON tmp.id_des = u.id
    GROUP BY u.id
    HAVING COUNT(*) = 2 -- Nombre d'éléments dans les clauses IN
    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 !

  17. #17
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut mohamed lamine 1996.

    Citation Envoyé par mohamed lamine 1996
    Si je pouvais résoudre ce problème (apparemment insolvable) sans modifier les tables serait très très génial.
    La partie utilse du traitement concerne les colonne "id_exp" et "id_des". Le reste n'intervient pas pour trouver la solution de ce que vous cherchez à faire.
    Si c'est la colonne "cas" qui vous dérange, vous pouvez la supprimer.
    Si c'est la colonne "val", rien ne vous empêche de la renommer soit en "id_exp" ou soit en "id_des" car selon le traitement, elles auront de toute façon la même valeur.
    Si j'ai ajouté cette colonne, c'est juste pour vous donner tous les cas possible que l'on peut rencontrer puisque vous n'avez pas la réciprocité des amitiés dans votre table.
    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
    select      x.val,
                u.nom,
                u.prenom
     
          from  (  select  id_des as val
                     from  `friend`
                    where  id_exp = 1
                    union
                   select  id_exp as val
                     from  `friend`
                    where  id_des = 1
                )    as x
     
    inner join  (  select  id_des as val
                     from  `friend`
                    where  id_exp = 2
                    union
                   select  id_exp as val
                     from  `friend`
                    where  id_des = 2
                )    as y
     
    inner join  user as u
            on  u.id = x.val
     
         where  x.val = y.val;
    Le problème n'est pas insoluble mais mal posé.
    Si vous aviez introduit la réciprocité, comme je l'ai dit, la solution serait bien plus simple : voir mon message #10.

    Citation Envoyé par mohamed lamine 1996
    En effet, je ne peux pas me permettre de modifier les tables ou l'une des tables pour ne pas risquer de causer d'autres erreurs à d'autres parties du code
    Personne ne vous a demandé de modifier l'une de vos tables.

    Vous nous avez demandé de résoudre un problème sous la forme d'une requête. Si les noms des colonnes ne vous plaisent pas, rien ne vous empêche de les rebaptiser à votre convenance.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  18. #18
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 346
    Points : 18 958
    Points
    18 958
    Par défaut
    Salut CinePhil.

    La solution consiste à faire une intersection entre deux sous-ensembles de données.
    Le premier sous-ensemble concerne les lignes ayant l'utilisateur "1".
    Le deuxième sous-ensemble concerne les lignes ayant l'utilisateur "2".

    Oui, mais voilà, le "1" et le "2" peuvent se trouver aussi bien dans la colonne "id_exp" et "id_des".
    Pourquoi ? Car "mohamed lamine 1996" n'a pas voulu utiliser la réciprocité dans sa table.
    Au cas où je ne serais pas assez clair, voici ce que j'entends par réciprocité.
    Si "1" désire être amis avec "2", dans la table il faut créer deux lignes, que voici :
    1 --> 2
    2 --> 1

    Il est vrai que l'on perd celui qui est demandeur de cette amitié.
    Mais l'amitié est réciproque. Autrement dit si "1" est amis avec "2", "2" est aussi amis avec "1", sinon cela n'a pas de sens.
    De ce fait, la solution que j'ai proposé dans mon message #10 est bien plus simple à mettre en oeuvre.
    Si vous ne comprenez pas bien ce que j'ai fait, je peux redonner cette solution.

    La solution que vous proposez est partielle car vous avez oublié un cas particulier, celui ou la demande est circulaire.
    1 --> 2
    2 --> 3
    3 --> 1

    Ainsi que la demande circulaire dans le sens inverse :
    1 --> 3
    3 --> 2
    2 --> 1

    A méditer !

    P.S.: ce que vous proposez comme solution correspond à mon message #10, sauf que je n'ai pas introduit la réciprocité des amitiés.
    La seule façon de résoudre le problème est de simuler sous MySql une intersection entre deux sous-ensembles, comme je l'ai fait.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  19. #19
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 736
    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 736
    Points : 52 447
    Points
    52 447
    Billets dans le blog
    5
    Par défaut
    La réciprocité est facile à traiter avec des vues qui font une UNION ALL de la table et son inverse.
    Dans la requête finale substituez la table par la vue et le tour est joué.
    Il faudra juste penser à faire un DISTINCT dans la table finale afin d'éviter les doublons

    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/ * * * * *

  20. #20
    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
    Citation Envoyé par Artemus
    La solution que vous proposez est partielle car vous avez oublié un cas particulier, celui ou la demande est circulaire.
    1 --> 2
    2 --> 3
    3 --> 1
    Alors, avec ces données la requête 3 de mon message :
    Citation Envoyé par CinéPhil
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT id_exp, id_des
    FROM friends
    WHERE id_exp IN(1, 2)
    	AND valide = 1
    UNION
    SELECT id_des, id_exp
    FROM friends
    WHERE id_des IN(1,2)
    	AND valide = 1
    Devrait donner ceci :
    id_exp, id_des
    1, 2
    1, 3
    2, 1
    2, 3

    3 apparaît bien deux fois dans la colonne id_des donc ma requête finale est bonne.

    Ainsi que la demande circulaire dans le sens inverse :
    1 --> 3
    3 --> 2
    2 --> 1
    Idem !
    Ma requête 3 va donner ceci (encore plus simple !) :
    1, 3
    2, 3
    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 !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/08/2009, 11h48
  2. Export DLL et noms des points d'entrée
    Par Dozer dans le forum MFC
    Réponses: 5
    Dernier message: 03/06/2005, 10h49
  3. communication entre deux executables
    Par semenzato dans le forum MFC
    Réponses: 8
    Dernier message: 13/04/2005, 23h19
  4. Communication entre deux Threads
    Par rvzip64 dans le forum Langage
    Réponses: 13
    Dernier message: 28/01/2005, 10h14
  5. Réponses: 5
    Dernier message: 25/03/2003, 20h43

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