J'essaye actuellement de joindre 3 tables. La table principale est société, s'il y a 3 sociétés et 2 rôles existent dans la table des rôles, je veux que la sortie soit comme ceci:

Company1, Role 1, <iduser>
Company1, Role 2, <iduser>
Company2, Role 1, <iduser>
Company2, Role 2, <iduser>
Company3, Role 1, <iduser>
Company3, Role 2, <iduser>

Pour chaque rôle, il doit y avoir une ligne pour une entreprise. Si aucun utilisateur n'est associé à un rôle et à une entreprise, il doit simplement afficher: Companyname , Rolename , null

Schéma de la base de données:

CREATE TABLE [dbo].[role](
    [idrole] [int] IDENTITY(1,1) NOT NULL,
    [name] [nchar](100) NOT NULL,
 CONSTRAINT [PK_role] PRIMARY KEY CLUSTERED 
(
    [idrole] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[company](
    [idcompany] [int] IDENTITY(1,1) NOT NULL,
    [name] [nchar](100) NOT NULL,
 CONSTRAINT [PK_company] PRIMARY KEY CLUSTERED 
(
    [idcompany] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[user](
    [iduser] [int] IDENTITY(1,1) NOT NULL,
    [name] [nchar](100) NOT NULL,
    [idcompany] [int] NOT NULL,
    [idrole] [int] NULL,
 CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED 
(
    [iduser] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[user]  WITH CHECK ADD  CONSTRAINT [FK_user_company] FOREIGN KEY([idcompany])
REFERENCES [dbo].[company] ([idcompany])
GO

ALTER TABLE [dbo].[user] CHECK CONSTRAINT [FK_user_company]
GO

ALTER TABLE [dbo].[user]  WITH CHECK ADD  CONSTRAINT [FK_user_role] FOREIGN KEY([idrole])
REFERENCES [dbo].[role] ([idrole])
GO

ALTER TABLE [dbo].[user] CHECK CONSTRAINT [FK_user_role]
GO

Script de données de test:

INSERT INTO [test].[dbo].[company]
VALUES ('Company 1')

INSERT INTO [test].[dbo].[company]
VALUES ('Company 2')

INSERT INTO [test].[dbo].[company]
VALUES ('Company 3')


INSERT INTO [test].[dbo].[role]
VALUES ('Role 1')

INSERT INTO [test].[dbo].[role]
VALUES ('Role 2')

Tentative:

SELECT roles.name, users.iduser 
FROM [test].[dbo].[role] roles
JOIN [test].[dbo].[user] users ON roles.idrole = users.idrole
JOIN [test].[dbo].[company] company ON company.idcompany = users.idcompany

Veuillez indiquer quelle approche je peux utiliser pour y parvenir

0
mig_08 25 août 2020 à 23:40

2 réponses

Meilleure réponse

Étant donné que vous n’avez pas de relation entre un Role et un Company, je suppose que vous voulez chaque combinaison de Role / Company, où vous utilisez un CROSS JOIN.

Ensuite, vous LEFT JOIN votre table User est activée puisque vous voulez retourner null si un utilisateur n'existe pas pour un rôle d'entreprise donné.

SELECT C.[name], R.[name], U.iduser 
FROM [test].[dbo].[role] R
CROSS JOIN [test].[dbo].[company] C
LEFT JOIN [test].[dbo].[user] U ON U.idrole = R.idrole and U.idcompany = C.idcompany
ORDER BY C.[name], R.[name], U.iduser;

Notez l'utilisation d'alias plus courts pour plus de clarté.

2
Dale K 25 août 2020 à 21:23

Je pense que nous devons appliquer une jointure croisée des 2 tables que les tables Company et Role, puis joindre avec les utilisateurs

select * from (
     select idcompany, b.name as coname, a.name, a.idrole
         from company b
         cross join 
         (select idrole, name from role) a
    ) c
    left join dbuser d on c.idcompany = d.idrole
    order by c.coname, c.name
1
Dale K 25 août 2020 à 21:20