1
votes

Est-il possible d'écrire une requête SQL pour rechercher des données dans plusieurs colonnes en fonction d'une troisième valeur?

J'ai une base de données clients qui ressemble à ceci:

Select Users.Username, Users.UserType, Customers.CustomerID, Customers.Name
from Users 
left outer join UserLink on Users.Username = UserLink.Username
left outer join Customers on UserLink.LinkID = Customers.Route
where Users.UserType = 'R'

Certains utilisateurs sont de type C, et un ou plusieurs clients leur seraient attribués par numéro de client. Certains utilisateurs sont de type R et un ou plusieurs numéros de route leur seraient attribués, ce qui les relie à tous les clients de ces routes.

Select Users.Username, Users.UserType, Customers.CustomerID, Customers.Name
from Users 
left outer join UserLink on Users.Username = UserLink.Username
left outer join Customers on UserLink.LinkID = Customers.CustomerID
where Users.UserType = 'C'

Cela a pour effet que l'appareil d'Hector montre les clients 001 et 002, l'appareil de Jim montre le client 019 et l'appareil de Tonk montre les clients 001, 015 et 137. (Ce serait être respectivement un responsable de chaîne, un client et un représentant commercial.)

J'essaye de créer une requête qui montre tous les clients attachés à tous les utilisateurs, comme ceci:

UserID | Name                 | Type | ID  | Name            
-------------------------------------------------------------
00001  | Hector Lopez         | C    | 001 | John Smith Co.  
00001  | Hector Lopez         | C    | 002 | John Smith #2   
00003  | Tonk Lu              | R    | 001 | John Smith Co.
00003  | Tonk Lu              | R    | 015 | Casa del Sol
00003  | Tonk Lu              | R    | 137 | Mary Malones 
00309  | Jim Kirk             | C    | 019 | Partners       

Mais je m'accroche à la manière de gérer la logique R et C. J'ai deux requêtes, mais idéalement j'aimerais pouvoir exécuter une seule requête.

UserID | Name                 | Type | Link
---------------------------------------------
00001  | Hector Lopez         | C    | 001
00001  | Hector Lopez         | C    | 002
00003  | Tonk Lu              | R    | 132
00309  | Jim Kirk             | C    | 019

et

ID  | Name            | Route
------------------------------
001 | John Smith Co.  | 132
002 | John Smith #2   | 201
015 | Casa del Sol    | 132
019 | Partners        | 201
137 | Mary Malones    | 132

Est-ce possible? Les seules informations que j'ai pu trouver à propos de deux colonnes concernaient les données correspondantes sur plus d'une colonne, comme lorsque Year = '2010' et Mfg = 'Ford'.

Merci.


0 commentaires

4 Réponses :


1
votes

Vous pouvez utiliser plusieurs clauses dans la jointure. Il semble que vous vouliez quelque chose comme:

Select Users.Username, Users.UserType, Customers.CustomerID, Customers.Name
from Users 
left outer join UserLink 
 on Users.Username = UserLink.Username
left outer join Customers 
 on (Users.UserType='C' and UserLink.LinkID = Customers.CustomerID) 
  OR (Users.UserType='R' and UserLink.LinkID = Customers.Route)


0 commentaires

1
votes

Votre première option consiste à UNION ces deux requêtes que vous avez déjà.
Vous pouvez également utiliser des conditions dans la partie ON d'une clause JOIN :

SELECT Users.Username, Users.UserType, Customers.CustomerID, Customers.Name
FROM Users 
LEFT OUTER JOIN UserLink
    ON Users.Username = UserLink.Username
LEFT OUTER JOIN Customers
    ON UserLink.LinkID = Customers.CustomerID AND Users.UserType = 'C'
LEFT OUTER JOIN Customers
    ON UserLink.LinkID = Customers.Route AND Users.UserType = 'R'


0 commentaires

0
votes

Si je comprends bien, vous souhaitez joindre les deux tables, mais utilisez un champ déterminé par le type. Si tel est le cas, vous pouvez utiliser deux jointures de gauche et coalesce():

select c.*,
       coalesce(rr.name, rc.name) as name
from customers c left join
     routes rc
     on rc.link = c.id and rc.type = 'C' left join
     routes rr
     on rc.link = c.route and rc.type = 'R';

Je ne suis pas sûr de ce que vos requêtes doivent faire avec la question. La question ne fait référence qu'à deux tableaux.


0 commentaires

1
votes

Pas besoin de rejoindre deux fois; vous pouvez implémenter la logique avec des conditions de jointure ou ed:

UserID | Name         | Type | Link |  ID | Name          
-----: | :----------- | :--- | ---: | --: | :-------------
     1 | Hector Lopez | C    |    1 |   1 | John Smith Co.
     1 | Hector Lopez | C    |    2 |   2 | John Smith #2 
     3 | Tonk Lu      | R    |  132 |   1 | John Smith Co.
     3 | Tonk Lu      | R    |  132 |  15 | Casa del Sol  
     3 | Tonk Lu      | R    |  132 | 137 | Mary Malones  
   309 | Jim Kirk     | C    |   19 |  19 | Partners      

Démo sur DB Fiddled :

select
    l.*,
    u.ID,
    u.Name
from Users u
inner join UserLinks l
    on (l.Type = 'C' and l.Link = u.ID)
    or (l.Type = 'R' and l.Link = u.Route)
order by l.UserID, u.ID


0 commentaires