简体   繁体   English

在 Oracle SQL 中比较日期

[英]Comparing Dates in Oracle SQL

I'm trying to get it to display the number of employees that are hired after June 20, 1994,我试图让它显示 1994 年 6 月 20 日之后雇用的员工人数,

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > 31-DEC-95; 

But I get an error saying但我得到一个错误说

"JUN' invalid identifier. “JUN”无效标识符。

Please help, thanks!请帮忙,谢谢!

31-DEC-95 isn't a string, nor is 20-JUN-94 . 31-DEC-95不是字符串, 20-JUN-94也不是。 They're numbers with some extra stuff added on the end.它们是最后添加了一些额外内容的数字。 This should be '31-DEC-95' or '20-JUN-94' - note the single quote, ' .这应该是'31-DEC-95''20-JUN-94' - 注意单引号' This will enable you to do a string comparison.这将使您能够进行字符串比较。

However, you're not doing a string comparison;但是,您没有进行字符串比较; you're doing a date comparison .你正在做一个日期比较 You should transform your string into a date.您应该将字符串转换为日期。 Either by using the built-in TO_DATE() function, or a date literal .通过使用内置TO_DATE()函数或日期文字

TO_DATE()迄今为止()

select employee_id
  from employee
 where employee_date_hired > to_date('31-DEC-95','DD-MON-YY')

This method has a few unnecessary pitfalls这种方法有一些不必要的陷阱

  • As a_horse_with_no_name noted in the comments, DEC , doesn't necessarily mean December.正如评论中指出的 a_horse_with_no_name , DEC不一定意味着 12 月。 It depends on your NLS_DATE_LANGUAGE and NLS_DATE_FORMAT settings.这取决于您的NLS_DATE_LANGUAGENLS_DATE_FORMAT设置。 To ensure that your comparison will work in any locale you can use the datetime format model MM instead为确保您的比较适用于任何语言环境,您可以改用日期时间格式模型MM
  • The year '95 is inexact. 95 年是不准确的。 You know you mean 1995, but what if it was '50, is that 1950 or 2050?你知道你的意思是 1995 年,但如果是 50 年,那是 1950 年还是 2050 年? It's always best to be explicit最好是明确的
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

Date literals日期文字

A date literal is part of the ANSI standard, which means you don't have to use an Oracle specific function.日期文字是 ANSI 标准的一部分,这意味着您不必使用 Oracle 特定的函数。 When using a literal you must specify your date in the format YYYY-MM-DD and you cannot include a time element.使用文字时,您必须YYYY-MM-DD格式指定日期,并且不能包含时间元素。

select employee_id
  from employee
 where employee_date_hired > date '1995-12-31'

Remember that the Oracle date datatype includes a time element, so the date without a time portion is equivalent to 1995-12-31 00:00:00 .请记住,Oracle 日期数据类型包含一个时间元素,因此没有时间部分的日期相当于1995-12-31 00:00:00

If you want to include a time portion then you'd have to use a timestamp literal, which takes the format YYYY-MM-DD HH24:MI:SS[.FF0-9]如果要包含时间部分,则必须使用时间戳文字,其格式YYYY-MM-DD HH24:MI:SS[.FF0-9]

select employee_id
  from employee
 where employee_date_hired > timestamp '1995-12-31 12:31:02'

Further information更多信息

NLS_DATE_LANGUAGE is derived from NLS_LANGUAGE and NLS_DATE_FORMAT is derived from NLS_TERRITORY . NLS_DATE_LANGUAGE派生自NLS_LANGUAGE并且NLS_DATE_FORMAT派生自NLS_TERRITORY These are set when you initially created the database but they can be altered by changing your initialization parameters file - only if really required - or at the session level by using the ALTER SESSION syntax.这些是在您最初创建数据库时设置的,但可以通过更改初始化参数文件(仅在确实需要时)或在会话级别使用ALTER SESSION语法来更改它们。 For instance:例如:

alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';

This means:这表示:

  • DD numeric day of the month, 1 - 31 DD数字日期,1 - 31
  • MM numeric month of the year, 01 - 12 ( January is 01 ) MM一年中的数字月份,01 - 12(一月是 01)
  • YYYY 4 digit year - in my opinion this is always better than a 2 digit year YY as there is no confusion with what century you're referring to. YYYY 4 位数年份 - 在我看来,这总是比 2 位数年份YY好,因为与您所指的世纪没有混淆。
  • HH24 hour of the day, 0 - 23 HH24小时,0 - 23
  • MI minute of the hour, 0 - 59小时的MI分钟,0 - 59
  • SS second of the minute, 0-59 SS分秒,0-59

You can find out your current language and date language settings by querying V$NLS_PARAMETERSs and the full gamut of valid values by querying V$NLS_VALID_VALUES .您可以通过查询V$NLS_PARAMETERSs找到您当前的语言和日期语言设置,并通过查询V$NLS_VALID_VALUES有效值的全部范围。

Further reading进一步阅读


Incidentally, if you want the count(*) you need to group by employee_id顺便说一句,如果你想要count(*)你需要按employee_id分组

select employee_id, count(*)
  from employee
 where employee_date_hired > date '1995-12-31'
 group by employee_id

This gives you the count per employee_id .这为您提供了每个employee_id的计数。

Conclusion,结论,

to_char works in its own way to_char以自己的方式工作

So,所以,

Always use this format YYYY-MM-DD for comparison instead of MM-DD-YY or DD-MM-YYYY or any other format始终使用此格式YYYY-MM-DD进行比较,而不是MM-DD-YYDD-MM-YYYY或任何其他格式

You can use trunc and to_date as follows:您可以按如下方式使用 trunc 和 to_date:

select TO_CHAR (g.FECHA, 'DD-MM-YYYY HH24:MI:SS') fecha_salida, g.NUMERO_GUIA, g.BOD_ORIGEN, g.TIPO_GUIA, dg.DOC_NUMERO, dg.* 
from ils_det_guia dg, ils_guia g
where dg.NUMERO_GUIA = g.NUMERO_GUIA and dg.TIPO_GUIA = g.TIPO_GUIA and dg.BOD_ORIGEN = g.BOD_ORIGEN
and dg.LAB_CODIGO = 56 
and trunc(g.FECHA) > to_date('01/02/15','DD/MM/YY')
order by g.FECHA;

from your query:根据您的查询:

Select employee_id, count(*) From Employee 
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95' 

i think its not to display the number of employees that are hired after June 20, 1994. if you want show number of employees, you can use:我认为它不显示 1994 年 6 月 20 日之后雇用的员工人数。如果要显示员工人数,可以使用:

Select count(*) From Employee 
Where to_char(employee_date_hired, 'YYYMMMDDD') > 19940620 

I think for best practice to compare dates you can use:我认为最佳做法是比较您可以使用的日期:

employee_date_hired > TO_DATE('20-06-1994', 'DD-MM-YYYY');
or
to_char(employee_date_hired, 'YYYMMMDDD') > 19940620;

Single quote must be there, since date converted to character.单引号必须在那里,因为日期转换为字符。

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95';

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

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