我想计算学生表中指定特定年份的男,女,全学生人数。我希望结果能够以下列形式显示:
====================================
| Label | Value | Year |
====================================
| Male | 0 | 2013 |
| Female | 23 | 2013 |
| Total | 23 | 2013 |
====================================
如果指定年份没有男性/女性匹配,则查询应显示0。知道如何才能实现这一目标吗?
提前致谢
答案 0 :(得分:12)
考虑以下问题:
select
max(registeredYear) as year,
count(case when gender='Male' then 1 end) as male_cnt,
count(case when gender='Female' then 1 end) as female_cnt,
count(*) as total_cnt
from student
where registeredYear = 2013
group by registeredYear;
结果如下:
Year male_cnt female_cnt total_cnt
---- -------- ---------- ---------
2013 0 23 23
您可以将此结果转换为所需的表单。如果您想在查询中执行此操作,则可以这样执行:
with t as (
select
max(registeredYear) as year,
count(case when gender='Male' then 1 end) as male_cnt,
count(case when gender='Female' then 1 end) as female_cnt,
count(*) as total_cnt
from student
where registeredYear = 2013
group by registeredYear)
select 'Male', male_cnt as male, year from t
union all
select 'Female', female_cnt as male, year from t
union all
select 'Total', total_cnt as male, year from t
;
答案 1 :(得分:5)
您应该使用:
select name, COUNT(*)as tot,
COUNT(case when details.gender='male' then 1 end) as male,
COUNT(case when details.gender='female' then 1 end) as female
from details group by name
答案 2 :(得分:1)
自shouldn't mix grid formatting with data retrieval
以来SELECT
SUM(CASE WHEN gender = 'Male' THEN 1 ELSE 0 END) as MaleCount,
SUM(CASE WHEN gender = 'Female' THEN 1 ELSE 0 END) as FemaleCount,
COUNT(*) as TotalCount
FROM student
WHERE registeredYear = 2013
答案 3 :(得分:1)
我相信只需通过学生表一次就可以获得这样的效率。只需根据需要更改年度CTE。
with
year as
(
select '2013' year
),
gender as (
select 'Male' gender
union all
select 'Female' gender
)
select coalesce(g.gender,'Total') "Label",
count(s.gender) "Value",
y.year "Year"
from gender g
cross join year y
left join student s
on s.gender = g.gender
and s.year = y.year
group by grouping sets( (g.gender, y.year), (y.year) )
order by case g.gender when 'Male' then 1 when 'Female' then 2 else 3 end
;
完全标准化的数据模型可能同时具有学年和性别表,因此不需要CTE。 (除非你真的想要返回没有任何数据的年份的行)
这是一个没有学生ID和姓名的简单sqlfiddle演示,因为它们与手头的问题无关。
答案 4 :(得分:1)
您的要求似乎很简单,但它有两个并发症。首先是一行是另外两行的摘要。这表示在查询中使用rollup
或grouping sets
。
第二个是即使没有数据也要求拥有值。这表明使用"驱动程序"子查询。这样的子查询在分配值之前定义输出中的所有行。您使用带有left outer join
的驱动程序表。
未说明的要求可能只是提及一年。
以下查询方法将最终表单放在一起。然后左边加入摘要,从那里拉取值,如果有的话:
with year as (
select 2013 as Year
)
select driver.label, coalesce(s.value, 0) as Value, driver.Year
from ((select 'Male' as label, year from year
) union all
(select 'Female' as label, year from year
) union all
(select 'Total' as label, year from year
)
) driver left outer join
(select coalesce(Gender, 'Total') as Gender, year.year, count(*) as value
from Students cross join year
group by Gender with Rollup
) s
on driver.year = s.year;
这假设性别被表示为"男性"和"女性"并且数据中有一个名为year
的列(没有样本输入或表格格式,必须猜测列名和样本值)。
答案 5 :(得分:0)
只需运行此查询...
SELECT
MAX(registeredYear) as Year
,SUM(CASE WHEN gender = 'Male' THEN 1 END) AS Male
,SUM(CASE WHEN gender = 'Female' THEN 1 END) AS Female
,SUM(CASE WHEN gender IS NOT NULL THEN 1 ELSE 0 END) AS Total
FROM from student
WHERE registeredYear = 2013
GROUP BY registeredYear;
答案 6 :(得分:0)
类似的东西:
select 'Male' as Label, count(gender) as Value from student where gender= 'Male'
union (
select 'Female' as Label, count(gender) as Value from student where gender= 'Female' )
union (
select 'Total' as Label, count(gender) as Value from student )
答案 7 :(得分:0)
尝试这一点,假设在Gender或RegisteredYear中没有空值:
WITH AllYears AS
(
SELECT RegisteredYear
FROM Student
GROUP BY RegisteredYear
)
, AllGenders AS
(
SELECT Gender
FROM Student
GROUP BY Gender
)
, AllGendersAndYears AS
(
SELECT Gender, RegisteredYear
FROM AllGenders, AllYears
)
SELECT Gender, RegisteredYear, CountForGenderAndYear
FROM AllGendersAndYears
CROSS APPLY
(
SELECT COUNT(*) AS CountForGenderAndYear
FROM Student
WHERE Student.Gender = AllGendersAndYears.Gender
AND Student.RegisteredYear = AllGendersAndYears.RegisteredYear
) countForGenderAndYear
UNION ALL
SELECT 'Total', AllYears.RegisteredYear, CountForYear
FROM AllYears
CROSS APPLY
(
SELECT COUNT(*) AS CountForYear
FROM Student
WHERE Student.RegisteredYear = AllYears.RegisteredYear
) countForYear
答案 8 :(得分:0)
这是使用UNPIVOT的另一种变体。这个只专门搜索MALE和FEMALE,因此它不像我的另一个那样灵活(因为你需要对每个性别进行硬编码)。但它可能是效率最高的。
WITH AllYears (RegisteredYear) AS
(
--SELECT DISTINCT RegisteredYear
--FROM Student
--...OR...
SELECT 2014
)
, GenderAndYearCounts AS
(
SELECT RegisteredYear
, SUM(CASE Gender WHEN 'MALE' THEN 1 ELSE 0 END) MaleCount
, SUM(CASE Gender WHEN 'FEMALE' THEN 1 ELSE 0 END) FemaleCount
, COUNT(*) YearCount
FROM Student
GROUP BY RegisteredYear
)
, GenderAndYearCountsForAllYears AS
(
SELECT AllYears.RegisteredYear
, ISNULL(MaleCount, 0) AS MaleCount
, ISNULL(FemaleCount, 0) AS FemaleCount
, ISNULL(YearCount, 0) AS YearCount
FROM AllYears
LEFT JOIN GenderAndYearCounts ON GenderAndYearCounts.RegisteredYear = AllYears.RegisteredYear
)
SELECT Label, Value, RegisteredYear
FROM
(
SELECT RegisteredYear, MaleCount AS Male, FemaleCount AS Female, YearCount AS Total
FROM GenderAndYearCountsForAllYears
) allCounts
UNPIVOT
(
Value FOR Label IN (Male, Female, Total)
) unpivotted
答案 9 :(得分:0)
所有性别,然后是所有年份,然后是计数:
declare @Year int
set @Year = 2014
select labels.label,
counts.cnt,
@Year as registeredYear
from
(select 'Male' as label, 1 as sortOrder
union all
select 'Female', 2
union all
select 'All', 3) as labels
left join
(select gender,
count(1) cnt
from student
where registeredYear = @Year
group by gender) as counts
on labels.label = counts.gender
order by labels.sortOrder
答案 10 :(得分:0)
这对我有用。但是,在没有数据的情况下,M和F仍然无法显示0:
Select * from
(
SELECT isnull (SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END),0) as Male,
isnull(SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END),0) as Female,
registeredYear as 'year'
FROM student
WHERE registeredDate.Year = 2013 //could be a variable
group by registeredYear
) as s
UNPIVOT
(
value FOR gender IN (Male, Female)
) Sub
答案 11 :(得分:0)
select sp.CLASS_Name , count(*) as total
, sum( case when si.STDNT_GENDER = 1 then 1 else 0 end ) as Male
, sum( case when si.STDNT_GENDER = 0 then 1 else 0 end ) as Female
from SCHOOL_PLANE sp inner join STUDENT_INFO si
on sp.CLASS_ID=si.STDNT_CLASS_PLANE_ID group by sp.CLASS_Name
-------
select sp.CLASS_Name , count(*) as total
, sum( case si.STDNT_GENDER when 1 then 1 else 0 end ) as Male
, sum( case si.STDNT_GENDER when 0 then 1 else 0 end ) as Female
from SCHOOL_PLANE sp inner join STUDENT_INFO si
on sp.CLASS_ID=si.STDNT_CLASS_PLANE_ID group by sp.CLASS_Name
------------
select sp.CLASS_Name , count(*) as total
, count( case when si.STDNT_GENDER = 1 then 1 end ) as Male
, count( case when si.STDNT_GENDER = 0 then 1 end ) as Female
from SCHOOL_PLANE sp inner join STUDENT_INFO si
on sp.CLASS_ID=si.STDNT_CLASS_PLANE_ID group by sp.CLASS_Name
答案 12 :(得分:0)
从*中选择*
(选择年,将count(*)作为总数,求和(当性别='M'时为1,否则0结尾的情况)为男性,
mytable中的女性的总和(当性别='F'然后1否则0结束的情况)
年份= 2013
按性别分组,年份)
枢纽
(income_component_value
为(male,female,total)中的income_component_type
)