Reputation: 363
For exercise, I have created the following database.
I would like to be able to count() the number of dances in the table "dance" for each user.
This is the query
SELECT
[user].[id_user], [user].[user_name],
COUNT([dance].[dancer_2_id_user]) AS 'number of dances'
FROM
[user]
LEFT JOIN
[dance] ON [user].[id_user] = [dance].[dancer_2_id_user]
GROUP BY
[user].[id_user], [user].[user_name]
which returns the number of times the user is counted in the "dancer_2_id_user" column.
And this query
SELECT
[user].[id_user], [user].[user_name],
COUNT([dance].[dancer_1_id_user]) AS 'number of dances'
FROM
[user]
LEFT JOIN
[dance] ON [user].[id_user] = [dance].[dancer_1_id_user]
GROUP BY
[user].[id_user], [user].[user_name]
returns the number of times the user is counted in the "dancer_1_id_user" column.
I would like to put these two queries together as a user can appear in either column of the "dance" table to be able to count the total number of dances per user.
CREATE TABLE [user]
(
[id_user] INT PRIMARY KEY NOT NULL IDENTITY(1,1),
[user_name] VARCHAR(45) UNIQUE,
[User_Sex] CHAR(1),
[date_of_birth] DATE,
[account_type] INT,
[id_address] INT,
);
CREATE TABLE [address]
(
[id_address] INT PRIMARY KEY NOT NULL IDENTITY(1,1),
[street] VARCHAR(255),
[number] INT,
[locality] VARCHAR(255),
[city] VARCHAR(255),
[country_code] CHAR(2)
);
CREATE TABLE [membership]
(
[account_type] INT PRIMARY KEY NOT NULL IDENTITY(1,1),
[membership_name] VARCHAR(45),
[membership_price] DECIMAL(4,2)
);
CREATE TABLE [style]
(
[style_ref] INT PRIMARY KEY NOT NULL IDENTITY(1,1),
[style_name] VARCHAR(45)
);
CREATE TABLE [dance]
(
[id_dance] INT NOT NULL IDENTITY(1,1),
[dancer_1_id_user] INT,
[dancer_2_id_user] INT,
[dance_dtg] DATETIME,
[style_ref] INT,
FOREIGN KEY (dancer_1_id_user) REFERENCES [user] (id_user),
FOREIGN KEY (dancer_2_id_user) REFERENCES [user] (id_user),
FOREIGN KEY (style_ref) REFERENCES [style] (style_ref)
);
CREATE TABLE [user_dance_style]
(
[id_user] INT,
[style_ref] INT
FOREIGN KEY (id_user) REFERENCES [user] (id_user),
FOREIGN KEY (style_ref) REFERENCES [style] (style_ref)
)
ALTER TABLE [user]
ADD CONSTRAINT fk_user_memebership
FOREIGN KEY (account_type) REFERENCES membership (account_type),
CONSTRAINT fk_user_address
FOREIGN KEY (id_address) REFERENCES address (id_address);
-- disable all constraints
EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
INSERT INTO [membership] ([membership_name], [membership_price])
VALUES ('free', '0'), ('regular', '15'), ('premium', '30')
INSERT INTO [style]([style_name])
VALUES ('Salsa'), ('Bachata'), ('Kizomba')
GO
INSERT INTO [user] ([user_name], [User_Sex], [date_of_birth], [account_type], [id_address])
VALUES ('sara', 'f', '1990-04-23', '1', '1'),
('elenor', 'f', '1989-02-18', '1', '2'),
('eva', 'f', '1987-01-04','1','3'),
('mike', 'm', '1985-05-02', '1', '4'),
('phil', 'm', '1985-03-01', '1', '5'),
('laurent', 'm', '1986-02-14', '2', '6'),
('nidia', 'f', '1985-01-16', '2', '7'),
('franz', 'm', '1990-03-17', '2', '8'),
('stephan', 'm', '1991-05-23', '2', '9'),
('sandra', 'f', '1993-03-25', '3', '10'),
('virginie', 'f', '1999-05-03', '3', '11'),
('claire', 'f', '1992-02-24', '3', '12'),
('laurence', 'f', '1991-04-26', '3', '13'),
('pierre', 'm', '1987-02-14', '3', '14'),
('thierry', 'm', '1989-01-04', '3', '15'),
('nancy', 'f', '1950-04-15', '1', '16')
GO
INSERT INTO [address] ([street], [number], [locality], [city], [country_code])
VALUES
('av de l''exposition', '13', 'laeken', 'bruxelles', 'be'),
('rue cans', '2', 'ixelles', 'bruxelles', 'be'),
('rue goffart', '32', 'ixelles', 'bruxelles', 'be'),
('ch de haecht', '17', 'schaerbeek', 'bruxelles', 'be'),
('rue metsys', '108', 'schaerbeek', 'bruxelles', 'be'),
('rue du pré', '223', 'jette', 'bruxelles', 'be'),
('rue sergent sorenser', '65', 'ganshoren', 'bruxelles', 'be'),
('rue d''aumale', '38', 'anderlecht', 'bruxelles', 'be'),
('av de fré', '363', 'uccle', 'bruxelles', 'be'),
('rue de lisbonne', '52', 'saint gilles', 'bruxelles', 'be'),
('av neptune', '24', 'forest', 'bruxelles', 'be'),
('av mozart', '76', 'forest', 'bruxelles', 'be'),
('rue emile delva', '92', 'laeken', 'bruxelles', 'be'),
('av de la chasse', '68', 'etterbeek', 'bruxelles', 'be'),
('rue leopold 1', '42', 'laeken', 'bruxelles', 'be'),
('av charle woeste', '68', 'jette', 'bruxelles', 'be')
GO
INSERT INTO [user_dance_style] ([id_user], [style_ref])
VALUES
(1, 1),(1, 2),(1, 3),(2, 1),(2, 2),(2, 3),(3, 1),(3, 2),(4, 1),(4, 2),
(4, 3),(5, 2),(5, 3),(6, 1),(7, 3),(8, 3),(9, 1),(9, 2),(9, 3),(10, 1),
(10, 2),(10, 3),(11, 3),(12, 2),(13, 2),(14, 1)
GO
INSERT INTO [dance]([dancer_1_id_user], [dancer_2_id_user], [dance_dtg], [style_ref])
VALUES
(1, 2, convert(datetime, '2019-11-24 10:34:09 PM',20), 3),
(4, 2, convert(datetime, '2019-11-24 10:50:00 PM',20), 3),
(3, 5, convert(datetime, '2019-11-24 10:35:00 PM',20), 2),
(6, 1, convert(datetime, '2019-11-24 10:37:00 PM',20), 1),
(7, 2, convert(datetime, '2019-11-24 10:37:00 PM',20), 3),
(8, 1, convert(datetime, '2019-12-03 11:20:03 PM',20), 3),
(9, 3, convert(datetime, '2019-12-23 10:45:00 AM',20), 1),
(10, 12, convert(datetime, '2019-12-26 11:20:00 AM',20), 2),
(11, 4, convert(datetime, '2020-01-02 08:45:00 AM',20), 3),
(12, 5, convert(datetime, '2020-01-02 11:10:04 AM',20), 2),
(13, 12, convert(datetime, '2020-02-04 09:25:00 PM',20), 2),
(14, 10, convert(datetime, '2020-02-25 10:45:00 AM',20), 1),
(2, 14, convert(datetime, '2020-02-25 08:45:00 PM',20), 1),
(5, 10, convert(datetime, '2020-03-01 11:15:06 AM',20), 2)
GO
Upvotes: 1
Views: 99
Reputation: 164099
You can join user
to dance
with both conditions using the operator IN
:
SELECT u.[id_user], u.[user_name],
COUNT(d.id_dance) AS [number of dances]
FROM [user] u LEFT JOIN [dance] d
ON u.[id_user] IN (d.[dancer_1_id_user], d.[dancer_2_id_user])
GROUP BY u.[id_user], u.[user_name]
See the demo.
Results:
> id_user | user_name | number of dances
> ------: | :-------- | ---------------:
> 1 | sara | 3
> 2 | elenor | 4
> 3 | eva | 2
> 4 | mike | 2
> 5 | phil | 3
> 6 | laurent | 1
> 7 | nidia | 1
> 8 | franz | 1
> 9 | stephan | 1
> 10 | sandra | 3
> 11 | virginie | 1
> 12 | claire | 3
> 13 | laurence | 1
> 14 | pierre | 2
> 15 | thierry | 0
> 16 | nancy | 0
Upvotes: 1
Reputation: 7503
Try the following using union all
select
user_id,
user_name,
sum(number_of_dances) as number_of_dances
from
(
SELECT
[user].[id_user] as user_id,
[user].[user_name] as user_name,
count([dance].[dancer_2_id_user]) as number_of_dances
FROM [user]
left JOIN [dance]
ON [user].[id_user] = [dance].[dancer_2_id_user]
GROUP BY [user].[id_user], [user].[user_name]
union all
SELECT
[user].[id_user],
[user].[user_name],
count([dance].[dancer_1_id_user])
FROM [user]
left JOIN [dance]
ON [user].[id_user] = [dance].[dancer_1_id_user]
GROUP BY [user].[id_user], [user].[user_name]
)val
group by
user_id,
user_name
Upvotes: 1