2010-03-03 11 views
3

J'ai une table d'utilisateurs. Il y a trois autres tables: les développeurs, les gestionnaires, les testeurs. Toutes ces tables ont une clé étrangère user_id.joindre deux tables

J'ai besoin de trouver tous les utilisateurs qui sont soit développeur ou gestionnaire. À quoi ressemblera le sql?

Mise à jour: Quelqu'un peut être à la fois développeur et gestionnaire.

+0

Avez-vous pensé que vos données peuvent être trop normalisées? – Timothy

+0

À quoi vous attendez-vous lorsque vous êtes un développeur, un responsable ou les deux? Juste l'user_id? Sa fonction dans un enregistrement? Deux disques? –

+0

@Lieven Juste l'id_utilisateur –

Répondre

7

Une façon de le faire serait

SELECT u.*, 'Developer' 
FROM users u 
     INNER JOIN developer d ON d.user_id = u.user_id 
UNION ALL 
SELECT u.*, 'Manager' 
FROM users u 
     INNER JOIN manager m ON m.user_id = u.user_id 
0
SELECT 
    user_id 
    /* ...other desired columns from the user table... */ 
FROM 
    user 
WHERE 
    user_id IN (SELECT user_id FROM developer UNION SELECT user_id FROM manager) 

Ici, je me sers IN plutôt que EXISTE afin que les tables de développeur et gestionnaire ne doivent être interrogé une fois. Il est possible que l'optimiseur le fasse de toute façon, mais cela le rend explicite.

En outre, cette solution ne renvoie pas de doublons pour les utilisateurs à la fois gestionnaires et développeurs.

+0

J'utiliserais UNION ALL dans ce cas ... vous dédutiez inutilement le résultat de la sous-requête dû à UNION –

+0

@Roland: les moteurs s'en chargeront automatiquement. Même 'MySQL' est assez intelligent pour ignorer' DISTINCT' dans le prédicat 'IN'. – Quassnoi

+0

@Roland Bouman - Je me demandais d'où venait tout ce réflexe UNION ALL. Donc, c'est une chose de performance. Je ne pense pas que je vais changer, parce que l'instruction UNION est le seul endroit dans tout le langage SQL où la fonctionnalité correspond réellement à la théorie de la base de données relationnelle! –

2
SELECT * 
FROM users u 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM developers 
     WHERE user_id = u.id 
     UNION ALL 
     SELECT NULL 
     FROM managers 
     WHERE user_id = u.id 
     ) 
+0

Quassnoi - bien! mais vous avez une faute de frappe - les utilisateurs ont besoin d'un alias. –

+0

@Roland: nous avons vraiment besoin d'un analyseur de requêtes intégré sur SO! – Quassnoi

1
SELECT u.*, 
      CASE d.user_id IS NULL THEN 'N' ELSE 'Y' END is_developer, 
      CASE m.user_id IS NULL THEN 'N' ELSE 'Y' END is_manager 
FROM  users u    -- all users 
LEFT JOIN developers d   -- perhaps a developer 
ON  u.user_id = d.user_id 
LEFT JOIN manager m    -- perhaps a manager 
ON  u.user_id = m.user_id 
WHERE  d.user_id IS NOT NULL -- either a developer 
    OR  m.user_id IS NOT NULL -- or a manager (or both) 
Questions connexes