SQL: plusieurs SELECT au lieu de JOIN

Je ne suis pas complètement nouveau à SQL, mais cette fois je suis lent sur l'absorption. Pour une export de données, je dois sélectionner certaines données d'user, y compris deux JOINs. Les données ne sont pas liées, j'ai juste besoin des deux informations dans une feuille d'export.

J'ai créé un exemple. Le nom de groupe de colonne provient d'un JOIN et le cours de la colonne de l'autre JOIN:

╔════╦═══════════╦══════════╦═══════════╦════════════╗ ║ id ║ firstname ║ lastname ║ groupname ║ course ║ ╠════╬═══════════╬══════════╬═══════════╬════════════╣ ║ 1 ║ John ║ Doe ║ Manager ║ Management ║ ║ 1 ║ John ║ Doe ║ CEO ║ Management ║ ║ 1 ║ John ║ Doe ║ Manager ║ Logistics ║ ║ 1 ║ John ║ Doe ║ CEO ║ Logistics ║ ║ 1 ║ John ║ Doe ║ Manager ║ Leadership ║ ║ 1 ║ John ║ Doe ║ CEO ║ Leadership ║ ╚════╩═══════════╩══════════╩═══════════╩════════════╝ 

En raison de la nature de JOINS; la colonne groupname-column est dupliquée maintenant plusieurs fois. Mais ce que je veux vraiment, c'est quelque chose comme ça:

 ╔════╦═══════════╦══════════╦═══════════╦════════════╗ ║ id ║ firstname ║ lastname ║ groupname ║ course ║ ╠════╬═══════════╬══════════╬═══════════╬════════════╣ ║ 1 ║ John ║ Doe ║ Manager ║ ║ ║ 1 ║ John ║ Doe ║ CEO ║ ║ ║ 1 ║ John ║ Doe ║ ║ Management ║ ║ 1 ║ John ║ Doe ║ ║ Logistics ║ ║ 1 ║ John ║ Doe ║ ║ Leadership ║ ╚════╩═══════════╩══════════╩═══════════╩════════════╝ 

Je suppose que faire deux SELECT-Statements consécutive serait la meilleure option. Malheureusement, la requête originale avec JOINS et where-Arguments a comme 25 lignes de code, donc je ne voudrais pas le dupliquer. Existe-t-il un moyen de réaliser plus facilement mon path de sortie en faisant par exemple un UNION avec deux longues requêtes (voir ci-dessous pour un exemple simple dans ce cas)?

 SELECT u.[id] ,[firstname] ,[lastname] ,groupname ,'' AS course FROM [dbo].[users] u JOIN dbo.groups g ON u.id = g.userId UNION ALL SELECT u.[id] ,[firstname] ,[lastname] ,'' AS groupname ,course FROM [dbo].[users] u JOIN dbo.courses c ON u.id = c.userId 

Je pense que c'est beaucoup de façon de résoudre votre problème. Je vais vous donner la meilleure façon de penser.

Première solution : Utilisez simplement un WITH pour ne pas répéter votre requête de pièce commune comme suit:

 WITH CommonPart (id, firstname, lastname) AS ( Select id, firstname, lastname From [dbo].[users] -- Eventually a filter ... ) SELECT cp.* , g.groupname , '' AS course FROM CommonPart cp JOIN dbo.groups g ON cp.id = g.userId UNION ALL SELECT cp.* ,'' AS groupname ,c.course FROM CommonPart cp JOIN dbo.courses c ON cp.id = c.userId 

Seconde solution : Vous pouvez insert des valeurs NULL dans des courses et des groups et utiliser une simple LEFT JOIN. Mais je n'aime pas cette deuxième solution.

EDIT: Après insertion de valeurs nulles, cela ressemblerait à:

 Select u.id, u.firstname, u.lastname, g.groupname, c.course From [dbo].[users] u Left Join [dbo].[groups] g ON g.userId = u.id Left Join [dbo].[courses] c ON c.userId = u.id Where (g.groupname IS NULL and c.course IS NOT NULL) OR (g.groupname IS NOT NULL and c.course IS NULL) 

Vous pouvez créer un file UDF avec valeur de table avec la requête en question, puis créer un ALL UNION avec les deux UDF

Pro:
– Une requête beaucoup plus courte:

 SELECT * FROM [MY_UDF](Param 1, Param 2, ...)<br/> UNION ALL<br/> SELECT * FROM [MY_UDF](Different Param 1, Different Param 2, ...) 

Con:
– Vous devez créer la table UDF valorisée.

Sinon: Je pense que QUERY_1 UNION ALL QUERY_2 est probablement le path à parcourir.