以下是ERD
我想计算每个月的性别数量('男性'女性'),不论年份。
我到目前为止所尝试的是,我可以分别计算每个月的男性和女性人数,如下所示
查询
Select u.Gender, datename(month, p.EntryDate) month, COUNT(p.User_Id) count
from [HospitalManagement].[dbo].[Patients] p,[HospitalManagement].[dbo].[Users] u
where u.Id = p.User_Id
group by datename(month, p.EntryDate), u.Gender
结果
我想要它如下
预期结果
Month | MaleCount | FemaleCount
June | 0 | 2
November | 1 | 1
要实现上述目标,请尝试以下查询
查询
Select datename(month, p.EntryDate) month,
(select count(u.gender) from [HospitalManagement].[dbo].[Users] u
where u.Id = p.User_Id and u.Gender = 'Female'
group by u.Gender) female,
(select count(u.gender) from [HospitalManagement].[dbo].[Users] u
where u.Id = p.User_Id and u.Gender = 'Male'
group by u.Gender) male
from [HospitalManagement].[dbo].[Patients] p
group by datename(month, p.EntryDate)
错误
Column 'HospitalManagement.dbo.Patients.User_Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
以下是表格的创建语句(我使用 MSSql )
-- Creating table 'Users'
CREATE TABLE [dbo].[Users] (
[Id] bigint IDENTITY(1,1) NOT NULL,
[Email] nvarchar(max) NULL,
[Password] nvarchar(max) NULL,
[UserName] nvarchar(max) NULL,
[Age] bigint NULL,
[Gender] nvarchar(max) NULL,
[NRIC] nvarchar(max) NULL,
[Comments] nvarchar(max) NULL,
[Address] nvarchar(max) NULL,
[ContactNo] nvarchar(max) NULL,
[FullName] nvarchar(max) NULL
);
GO
-- Creating table 'Patients'
CREATE TABLE [dbo].[Patients] (
[Id] bigint IDENTITY(1,1) NOT NULL,
[Disease] nvarchar(max) NULL,
[Occupation] nvarchar(max) NULL,
[EntryDate] datetime NULL,
[EntryTime] time NULL,
[User_Id] bigint NOT NULL
);
GO
答案 0 :(得分:2)
如错误所示,您直接在select子句中使用User_Id列,该列在GROUP BY中不存在。
您可以将相关子查询更改为更快的LEFT JOIN(假设User_Id在Patients表中是唯一的)。
select
datename(month, p.EntryDate) mon,
count(case when u.Gender = 'Female' then 1 end) female_cnt,
count(case when u.Gender = 'Male' then 1 end) male_cnt
from [Patients] p left join [Users] u
on p.User_Id = u.Id
group by datename(month, p.EntryDate);
您可以使用查找CTE生成所有月份,然后像这样使用LEFT JOIN:
;WITH months(mn, mon) AS
(
SELECT 1, DATENAME(MONTH,DATEADD(month,0,GETDATE())) mon
UNION ALL
SELECT mn+1, DATENAME(MONTH,DATEADD(MONTH,mn,GETDATE()))
FROM months
WHERE mn < 12
)
select
m.mon mon,
count(case when u.Gender = 'Female' then 1 end) female_cnt,
count(case when u.Gender = 'Male' then 1 end) male_cnt
from months m left join [Patients] p
on m.mon = datename(month, p.EntryDate)
left join [Users] u
on p.User_Id = u.Id
group by m.mon;
答案 1 :(得分:0)
您可以尝试以下查询:
Select
datename(month, p.EntryDate) month,
COUNT(IF(u.Gender = 'Male', 1, NULL) AS MaleCount,
COUNT(IF(u.Gender = 'Female', 1, NULL) AS FemaleCount
from
[HospitalManagement].[dbo].[Patients] p,[HospitalManagement].[dbo].[Users] u
where
u.Id = p.User_Id
group by
datename(month, p.EntryDate)
答案 2 :(得分:0)
这就是我们在MySQL或Oracle中的表现。虽然没有尝试过MSSQL。但由于这些是标准的SQL函数(并且在MSSQL中可用),因此它也适用于MSSQL。
Select datename(month, p.EntryDate) month , SUM(CASE WHEN u.Gender = 'Male' THEN 1 ELSE 0) MaleCount, SUM(CASE WHEN u.Gender = 'Female' THEN 1 ELSE 0) FemaleCount,
from [HospitalManagement].[dbo].[Patients] p,[HospitalManagement].[dbo].[Users] u
where u.Id = p.User_Id
group by datename(month, p.EntryDate)
通常我会在特定性别的情况下添加1来获得结果。
注意:如果有任何语法错误,请告诉我错误,我可以更正。