简体   繁体   English

使用左表的条件执行右外部联接

[英]Perform right outer join with a condition for left table

I have two tables, 我有两张桌子

Student: 学生:

rollno  | name 
1       | Abc
2       | efg
3       | hij
4       | klm

Attendance: 出席:

name | date       |status
Abc  | 10-10-2013 | A
efg  | 10-10-2013 | A
Abc  | 11-10-2013 | A
hij  | 25-10-2013 | A

My required output is: 我需要的输出是:

Some query with where condition as "where date between '10-09-2013' and '13-10-2013' " 一些查询条件条件为“ '10 -09-2013'和'13 -10-2013'之间的日期”

rollno| name |count
1     | Abc  | 2
2     | efg  | 1
3     | hij  | 0
4     | klm  | 0

I tried using: 我尝试使用:

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

And the Output is: 输出为:

rollno| name |count
1   | Abc  | 2
2   | efg  | 1

I want the remaining values from the student table to also be appended. 我希望来自student表的其余值也要附加。 I have tried many different queries, but all have been unsuccessful. 我尝试了许多不同的查询,但都没有成功。 Is there a query that will return the required output above? 是否有查询将返回上面的所需输出?

You need to move the criteria from the where to the join: 您需要将条件从何处移动到联接:

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;

At the moment even though you have an outer join, by referring to the outer table in the where clause you effectively turn it into an inner join. 目前,即使您具有外部联接,也可以通过在where子句中引用外部表将其有效地转换为内部联接。 Where there is no match in attendance , s.Date will be NULL , and because NULL is not between '10-09-2013' and '13-10-2013' the rows are excluded. 如果attendance不匹配,则s.Date将为NULL ,并且由于NULL不在'10-09-2013' and '13-10-2013'因此将排除行。

It is not apparent from the question, but I would image that what you are actually looking for is this. 从这个问题来看并不明显,但我想想您实际上正在寻找的是这个。 It appears you are just after a count of entries in attendance where status = 'A' by student: 看来您只是在按学生人数计入状态为“ 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;

I have removed s.statuss from the group by, and changed the count so that there is only one row per student, rather than one row per status per student. 我从组中删除了s.statuss,并更改了计数,以使每个学生只有一行,而不是每个学生每个状态只有一行。 I have changed the column within the count to a column in the attendance status table, to ensure that you get a count of 0 when there are no entries in attendance. 我已将计数内的列更改为出勤状态表中的一列,以确保当没有出勤记录时您得到的计数为0。 if you use a column in students you will get a count of 1 even when there are no entries. 如果您在学生中使用一列,即使没有条目,您也会得到1的计数。 Finally, since you are only interested in entries with statuss = 'A' I have also moved this to the join condition. 最后,由于您仅对状态statuss = 'A'条目感兴趣,因此我也将其移至statuss = 'A'条件。

On one final note, it is advisable when using strings for dates to use the culture insensitive format yyyyMMdd , as this is completely unanbiguous, 20130201' is always the 1st February, and never 2nd January, whereas in your query 10-09-2013' could be 10th September, or 9th October, depending on your settings. 最后一点,建议在使用字符串作为日期时使用不区分文化的格式yyyyMMdd ,因为这是完全明确的, 20130201' is always the 1st February, and never 2nd January, whereas in your query 10-09-2013'可能是9月10日还是10月9日,具体取决于您的设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM