我有两张桌子,
学生:
rollno | name
1 | Abc
2 | efg
3 | hij
4 | klm
出勤:
name | date |status
Abc | 10-10-2013 | A
efg | 10-10-2013 | A
Abc | 11-10-2013 | A
hij | 25-10-2013 | A
我要求的输出是:
某些查询条件为“在'10 -09-2013'和'13 -10-2013之间的日期'”
rollno| name |count
1 | Abc | 2
2 | efg | 1
3 | hij | 0
4 | klm | 0
我尝试使用:
SELECT p.rollno,p.name,case when s.statuss='A' then COUNT(p.rollno) else '0' end as count
from attendance s
right outer join student p
on s.rollno=p.rollno
where s.date between '10-09-2013' and '13-10-2013'
group by p.rollno,p.regno,p.name,s.statuss
order by p.rollno
输出是:
rollno| name |count
1 | Abc | 2
2 | efg | 1
我希望还附加student表中的剩余值。我尝试了很多不同的查询,但都没有成功。是否有一个查询将返回上面的所需输出?
答案 0 :(得分:2)
您需要将条件从联接的位置移动:
SELECT p.rollno,p.name,case when s.statuss='A' then COUNT(p.rollno) else 0 end as count
from attendance s
right outer join student p
on s.rollno=p.rollno
and s.date between '10-09-2013' and '13-10-2013'
group by p.rollno,p.regno,p.name,s.statuss
order by p.rollno;
目前,即使你有一个外部联接,通过引用where子句中的外部表,你可以有效地将它转换为内部联接。如果attendance
中没有匹配项,则s.Date
将为NULL
,并且因为NULL
不在'10-09-2013' and '13-10-2013'
之间,所以排除了这些行。
这个问题并不明显,但我会想到你实际上正在寻找的是这个。看来你刚刚参加了一个参赛人数,其中状态=' A'由学生:
SELECT p.rollno,
p.name,
COUNT(s.statuss) as count
from attendance s
right outer join student p
on s.rollno=p.rollno
and s.date between '10-09-2013' and '13-10-2013'
AND s.statuss = 'A'
group by p.rollno,p.regno,p.name,
order by p.rollno;
我已从组中删除了s.statuss,并更改了计数,以便每个学生只有一行,而不是每个学生每个状态一行。我已将计数中的列更改为出勤状态表中的列,以确保在没有出席条目时计数为0。如果您在学生中使用专栏,即使没有参赛作品,您也会获得1分。最后,由于您只对statuss = 'A'
条目感兴趣,我还将其移至连接条件。
最后一点,建议使用日期字符串来使用不区分大小写的格式yyyyMMdd
,因为这完全是不明确的,20130201' is always the 1st February, and never 2nd January, whereas in your query
10-09-2013'可能是9月10日或10月9日,具体取决于您的设置。