例如,如果我有一个表'studentActivities'
,其中每次学生进行活动时都会记录。像这样:
activity countryofbirth name event_date
School Swimming USA Bob 5/21/2017 12:50
Park Swimming Australia Sarah 2/11/2017 19:50
Park Swimming Australia Sarah 2/13/2017 16:50
Park Running USA Bob 2/10/2017 11:50
School Tennis USA Bob 2/12/2017 11:50
NULL USA Jane 8/4/2016 13:30
我正在尝试根据学生In-School Actvity
或Out-of-School Activity
来计算学生所做的不同活动。
这是4
校内活动的特色:
School Swimming, School Running, School Soccer, School Tennis
我想得到的是一张表:
Student_Name Country_of_Birth In-School_Activities Out_of_School_Activities
Bob USA 2 1
Sarah Australia 0 1
Jane USA 0 0
我试过了:
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth AS County_of_Birth],
COUNT (DISTINCT activity) as [In-School Activities]
FROM studentActivities
WHERE studentActivities.activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
UNION
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth AS [County_of_Birth],
COUNT (DISTINCT activity) as [Out_of_School Activities]
FROM studentActivities
WHERE studentActivities.activity NOT IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
但这并没有给我我想要的结果。我怎样才能得到我想要的结果?
答案 0 :(得分:1)
您应该使用Full Outer Join
WITH InSchool AS (
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth ,
COUNT (DISTINCT activity) as [In-School Activities]
FROM studentActivities
WHERE studentActivities.activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
)
, OutOfSchool AS (
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth,
COUNT (DISTINCT activity) as [Out_of_School Activities]
FROM studentActivities
WHERE studentActivities.activity NOT IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
)
SELECT
COALESCE(InSchool.student_name, OutOfSchool.student_name) [Student_Name],
COALESCE(InSchool.CountryOfBirth, OutOfSchool.CountryOfBirth) CountryOfBirth,
COALESCE(InSchool.[In-School Activities],0) [In-School Activities],
COALESCE(OutOfSchool.[Out_of_School Activities],0) [Out_of_School Activities]
FROM InSchool
FULL OUTER JOIN OutOfSchool
ON InSchool.[student_name] = OutOfSchool.[Student_name]
AND InSchool.CountryOfBirth = OutOfSchool.CountryOfBirth
答案 1 :(得分:1)
这就是我想到的,我没有验证,但这就是我完成任务的方式
SELECT
name AS [student_name],
countryofbirth AS [Manufacturer],
sum (activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')) as [In-School Activities],
sum (activity NOT IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')) as [Out_of_School Activities]
FROM (select distinct studentActivities.name, studentActivities.countryofbirth, activity) x
GROUP BY name, countryofbirth;
答案 2 :(得分:1)
你应该使用联接(而不是联盟)
select a.[student_name], a.[student_name], a.[In-School Activities], b.[Out_of_School Activities]
from (
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth AS [Manufacturer],
COUNT (DISTINCT activity) as [In-School Activities]
FROM studentActivities
WHERE studentActivities.activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
) a
left join (
SELECT
studentActivities.name AS [student_name],
studentActivities.countryofbirth AS [Manufacturer],
COUNT (DISTINCT activity) as [Out_of_School Activities]
FROM studentActivities
WHERE studentActivities.activity NOT IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
GROUP BY studentActivities.name, studentActivities.countryofbirth
) b on a.[student_name] = b.[student_name] and a.[Manufacturer] = b.[Manufacturer]
答案 3 :(得分:1)
我会使用Case语句:
SELECT
Sa.name AS [student_name],
Sa.countryofbirth,
Sum(Case when sa.activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
then 1 else 0 end) as In_school_Activities,
Sum(Case when sa.activity IN ('School Swimming', 'School Running', 'School Soccer', 'School Tennis')
then 0 else 1 end) as Out_of_school_Activities
FROM (select distinct student_name, country _of_birth, activity from studentActivities) sa
GROUP BY sa.name, sa.countryofbirth
请注意,在任何非平凡的应用程序中,名称永远不能被视为唯一。如果您有一个标识符(并且您应该随时拥有名称),那么最好对其进行分组。
答案 4 :(得分:1)
Pivot会解决这个问题。我使用您提供的数据对其进行了测试,并且按预期工作。
SELECT
Name
,countryofbirth
, [In-School Activity]
,[Out-of-School Activity]
FROM(
SELECT
name
,countryofbirth
,CASE Activity
WHEN 'School Swimming' THEN 'In-School Activity'
WHEN 'School Running' THEN 'In-School Activity'
WHEN 'School Soccer' THEN 'In-School Activity'
WHEN 'School Tennis' THEN 'In-School Activity'
ELSE 'Out-of-School Activity'
END class
FROM studentactivities
WHERE Activity IS NOT NULL
)AS base
PIVOT(
COUNT (CLASS)
FOR CLASS IN ([In-School Activity],[Out-of-School Activity])
)AS Pivoted
答案 5 :(得分:1)
;WITH cte
AS (
SELECT DISTINCT NAME AS [student_name]
,countryofbirth
,activity
,CASE
WHEN activity IN (
'School Swimming'
,'School Running'
,'School Soccer'
,'School Tennis'
)
THEN 1
ELSE 0
END AS [In-school_activity_count]
,CASE
WHEN activity IS NOT NULL
AND activity NOT IN (
'School Swimming'
,'School Running'
,'School Soccer'
,'School Tennis'
)
THEN 1
ELSE 0
END AS [Out-of-school_activity_count]
FROM studentActivities
)
SELECT student_name
,countryofbirth
,SUM([In-school_activity_count]) AS [In-School_Activities]
,SUM([Out-of-school_activity_count]) AS [Out_of_School_Activities]
FROM cte
GROUP BY student_name
,countryofbirth
答案 6 :(得分:1)
使用count(distinct ...)
select
Name
, CountryOfBirth
, InSchoolActivies = count(distinct case when activity in ('School Swimming', 'School Running', 'School Soccer', 'School Tennis') then activity end)
, OutOfSchoolActivies = count(distinct case when activity not in ('School Swimming', 'School Running', 'School Soccer', 'School Tennis') then activity end)
from StudentActivites
group by Name, CountryOfBirth
rextester演示:http://rextester.com/EMUWU73595
返回:(在样本数据中更正Bob的出生国家后)
+-------+----------------+------------------+---------------------+
| Name | CountryOfBirth | InSchoolActivies | OutOfSchoolActivies |
+-------+----------------+------------------+---------------------+
| Bob | USA | 2 | 1 |
| Jane | USA | 0 | 0 |
| Sarah | Australia | 0 | 1 |
+-------+----------------+------------------+---------------------+
答案 7 :(得分:1)
以下内容很简单,有效:
select name,countryofbirth,sum(schoolflag) as
In_School_Activity,sum(nonschool) Out_Of_School_Activity
from
(
select activity,name,countryofbirth,
case when activity like 'School%' then 1 else 0 end as schoolflag ,
case when activity not like 'School%' then 1 else 0 end as nonschool
from schoolactivity
)a
group by name,countryofbirth