Datediff()用于查找日期差的替代项是什么?

问题描述 投票:0回答:2

我正在尝试编写一个查询,该查询将返回未参加任何课程超过5个月的学生的列表。我认为我的逻辑正确,但是无法在SQL Plus中使用Datediff()。我想知道是否还有其他方法。

查询:

SELECT s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date
FROM Student s
INNER JOIN Enrolled_In e ON s.Reg_No = e.Reg_No
WHERE (s.Reg_No != e.Reg_No) AND (DATEDIFF(months, GETDATE(), s.Admission_Date) > 5);
sql oracle date select oracle11g
2个回答
3
投票

Oracle具有months_between function

months_between

您也可以使用AND MONTHS_BETWEEN(sysdate, s.Admission_Date) > 5

add_months function

[如果有的话,它仍然可以在该列上使用索引。

并且您可以使用间隔,但是由于月份长度不同,因此使用月份间隔进行加/减会引起问题。


虽然您的逻辑看起来不正确。首先,您需要将add_months值与AND s.Admission_Date < ADD_MONTHS(sysdate, -5) reg_no都进行比较,这两者不能同时为真。您还在查看=,而不是!=中的日期。

[您想查找最近五个月没有上过课的学生,因此您可以找到最新的上学并过滤掉这些,例如(猜测您有一个名为s.admission_date的列,您需要检查):

enrolled_in

它将找到某个时候入学但最近五个月没有入学的学生。如果要包括从未入学的学生,可以使用外部联接:

enrolled_date

或者因为您没有从注册中报告任何数据,您可以将SELECT s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date FROM Student s INNER JOIN Enrolled_In e ON s.Reg_No = e.Reg_No GROUP BY s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date HAVING MAX(e.Enrolled_Date) < ADD_MONTHS(sysdate, -5) 与子查询一起使用以查找任何最近的课程:

SELECT s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date
FROM Student s
LEFT OUTER JOIN Enrolled_In e ON s.Reg_No = e.Reg_No
AND e.Enrolled_Date >= ADD_MONTHS(sysdate, -5)
GROUP BY s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date
HAVING COUNT(e.Enrolled_Date) = 0

找到在学生表中但不在登记表中的学生

您也可以使用not exists查询-只需检查日期即可:

not exists

但是,正如您自己发现的那样,使用外部联接和空检查或计数也可以。


2
投票

我认为您查询的逻辑不正确。如果您希望最近5个月内未注册的学生,可以通过使用获取上次注册日期的相关子查询来过滤students表来表述:

SELECT s.Reg_No, s.First_Name, s.Last_Name, s.Admission_Date
FROM Student s
WHERE NOT EXISTS (
    SELECT null
    FROM Enrolled_In e
    WHERE e.Reg_No = s.Reg_No
    AND e.Enrolled_Date >= ADD_MONTHS(sysdate, -5)
);
    
© www.soinside.com 2019 - 2024. All rights reserved.