Dette indlæg forsøger jeg at forklare mange ting om dato i oracle som oracle sql-datofunktioner, oracle sql-datoformat, oracle sql-datosammenligning, oracle-datoforskel i år, oracle-datoforskel i dage, oracle-datoforskel i måneder
Oracle har leveret dato- og tidsstempeltyper til lagring af dato- og tidsoplysninger i Oracle-databasen.
Datodatatype
DATE er orakeldatatypen, som vi alle kender, når vi tænker på at repræsentere dato- og tidsværdier. Den har evnen til at gemme måned, dag,
år, århundrede, timer, minutter og sekunder. Problemet med DATE-datatypen er dens granularitet, når man forsøger at bestemme et tidsinterval mellem to hændelser, når hændelserne sker inden for et sekund efter hinanden. Dette problem er løst med TIMESTAMP-datatypen
Tidsstempel
Oracle har udvidet på DATE-datatypen og har givet os TIMESTAMP-datatypen, som gemmer al den information, som DATE-datatypen gemmer, men også inkluderer brøkdele af sekunder. Hvis du vil konvertere en DATE-datatype til et TIMESTAMP-datatypeformat, kan du bruge CAST-funktionen
SQL> SELECT CAST(last_login_date AS TIMESTAMP) "Date" FROM users; Date ----------------------------------------------------- 20-APR-16 01.55.14.000000 PM 21-JUN-16 14.16.36.000000 AM 21-JUL-16 10.16.36.000000 AM 21-SEP-16 11.16.36.000000 AM 21-DEC-16 11.16.36.000000 AM
For at få systemdatoen og -tiden returneret i en TIMESTAMP-datatype, kan du bruge SYSTIMESTAMP-funktionen, såsom:
SQL> SELECT SYSTIMESTAMP FROM DUAL; SYSTIMESTAMP --------------------------------------------------------------------------- 01-SEP-19 01.02.17.158913 PM -04:00
Et vigtigt punkt
1)Både DATE- og TIMESTAMP-typer indeholder altid en dato- og tidskomponent. Præcis midnat er klokken 00:00:00.
SELECT TO_CHAR(SYSDATE, 'MM/DD/YYYY HH:MI:SS AM') date_with_time ,TRUNC(SYSDATE) today ,TO_CHAR(TRUNC(SYSDATE), 'MM/DD/YYYY HH:MI:SS AM') date_with_time_midnight FROM dual 2 3 4 ;DATE_WITH_TIME TODAY DATE_WITH_TIME_MIDNIGHT ---------------------- --------- ---------------------- 10/27/2016 11:01:00 AM 27-OCT-16 10/27/2016 12:00:00 AM
2) Stol aldrig på implicitte konverteringer af strenge til datoer eller datoer til strenge. Udfør altid eksplicit konverteringerne med funktionerne TO_CHAR, TO_DATE og TO_TIMESTAMP, eller brug bogstaverne ANSI DATE eller TIMESTAMP.
3) Når du sammenligner dato eller tidsstempel, skal du altid overveje virkningen af tidskomponenten. Hvis du ønsker at kassere tidskomponenten fra sammenligningen, skal du bruge TRUNC eller RUND funktioner til at fjerne det fra begge sider af sammenligningen.
select * from fnd_table where trunc(creation_date) < trunc(sysdate);
4) Du kan vise det påkrævede datoformat ved hjælp af nls_date_format på sessionsniveau
Skift datoformat i Oracle ved hjælp af nls_date_format
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD'; select sysdate from dual; ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI:SS'; select sysdate from dual; alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss'; select sysdate from dual;
5) Her er en god oversigt over de tidsformater vi kan bruge
Element | Beskrivelse |
Datoformatelementer | |
SCC eller CC | Århundrede; S præfikser BC-dato med – |
ÅÅÅÅ eller ÅÅÅÅ | År; S præfikser BC-dato med – |
ÅÅÅ eller ÅÅ eller Y | Sidste 3, 2 eller 1 ciffer i året |
Å,ÅÅÅ | Årtal med komma i denne position |
IYYY, IYY, IY, I | 4, 3, 2 eller 1 cifret årstal baseret på ISO-standarden |
SYEAR eller YEAR | År angivet; S præfikser BC-dato med – |
BC eller AD | BC/AD-indikator |
B.C. eller A.D. | BC/AC-indikator med punktum |
Q | Kvartal af året |
MM | Måned, tocifret værdi |
MÅNED | Månedens navn polstret med tomme felter til en længde på 9 tegn |
MÅN | Månedens navn, forkortelse på tre bogstaver |
RM | romertalsmåned |
WW eller W | Uge i året eller måneden |
DDD eller DD eller D | Dag i år, måned eller uge |
DAG | Dagens navn polstret med tomme felter til en længde på 9 tegn |
DY | Dagens navn; 3 bogstaver forkortelse |
J | Juliansk dag; antallet af dage siden 31. december 4713 f.Kr. |
Tidsformatelementer | |
AM eller PM | Meridianindikator |
A.M. eller P.M. | Meridianindikator med perioder |
HH eller HH12 eller HH24 | Time på dagen eller time(1-12) eller time(0-23) |
MI | Minut (0-59) |
SS | Anden (0-59) |
SSSSS | Sekunder efter midnat (0-86399) |
Suffikser | |
TH | Ordinalnummer (dvs. DDTH for 5TH) |
SP | Stavet nummer (dvs. DDSP for FEM) |
SPTH eller THSP | Stavede ordenstal (dvs. DDSPTH for FIFTH) |
Andre formateringselementer | |
/ , . | tegnsætning gengives i resultatet |
“af” | Citeret streng gengives i resultatet |
oracle-datofunktioner
Vi lærte om datatype for dato og tidsstempel i det foregående afsnit. Vi vil nu se vigtige oracle-datofunktioner i detaljer, og hvordan vi kan bruge dem
ADD_MONTHS
Datofunktion | Beskrivelse |
ADD_MONTHS (dato, n) | Returnerer en datoværdi efter tilføjelse af 'n' måneder til datoen 'x'. |
select ADD_MONTHS ('16-Sep-81', 3) from dual ---------------------------- 16-Dec-81
ADD_MONTHS flytter altid datoen med hele måneder. Du kan angive en brøkværdi for parameteren month_shift, men ADD_MONTHS vil altid runde ned til hele tallet nærmest nul, som vist i disse
eksempler:
Så
select ADD_MONTHS ('28-FEB-2005', 1.5) from dual ------------------------------------------- 31-Mar-2005
Vi kan også bruge negative værdier
select ADD_MONTHS ('28-FEB-2005', -1) from dual ------------------------------ 31-Jan-2005
Sidste_dag
Datofunktion | Beskrivelse |
SIDSTE_DAG (x) | Den bruges til at bestemme antallet af dage tilbage i en måned fra den angivne dato 'x'. |
Funktionen SIDSTE_DAG returnerer datoen for den sidste dag i måneden for en given dato. Denne funktion er nyttig, fordi antallet af dage i en måned varierer i løbet af året.
select LAST_DAY ('01-Jun-16') from dual ---------------------------------------------------- 30-Jun-2016
Næste_dag
Datofunktion | Beskrivelse |
NEXT_DAY (x, week_day) | Returnerer den næste dato for 'ugedag' på eller efter datoen 'x' indtræffer. |
NEXT_DAY returnerer datoen for den første ugedag navngivet efter dag, som er senere end datoen. Returtypen er altid DATO, uanset datoens datatype. Argumentationsdagen skal være en dag i ugen på datosproget for din session, enten det fulde navn eller forkortelsen
select NEXT_DAY ('01-Jun-08', 'Wednesday') from dual ------------------------------------------- 04-JUN-08
MONTHS_BETWEEN
Datofunktion | Beskrivelse |
MONTHS_BETWEEN (x1, x2) | Returnerer antallet af måneder mellem dato x1 og x2. |
Funktionen MONTHS_BETWEEN beregner antallet af måneder mellem to datoer og returnerer denne forskel som et tal
Regler for beregningen er
1)Hvis dato1 kommer efter dato2, så returnerer MONTHS_BETWEEN et positivt tal.
2) Hvis dato1 kommer før dato2, returnerer MONTHS_BETWEEN et negativt tal.
3) Hvis dato1 og dato2 begge falder på den sidste dag af deres respektive måneder, returnerer MONTHS_BETWEEN et helt tal (ingen brøkkomponent).
4)Hvis dato1 og dato2 er i forskellige måneder, og mindst én af datoerne ikke er den sidste dag i måneden, returnerer MONTHS_BETWEEN en brøktal. Brøkkomponenten beregnes på 31-dages basis og tager også højde for eventuelle forskelle i tidskomponenten dato1 og dato2.
Eksempler
select MONTHS_BETWEEN ('29-FEB-2016', '31-MAR-20') from dual -------------------------------------------------------------------------------- -1 select MONTHS_BETWEEN ('31-MAR-1995', '28-FEB-1994') from dual ------------------------------------------------------------------------------- 13 select MONTHS_BETWEEN ('31-JAN-2006', '10-MAR-2006') from dual ---------------------------------------------------------------------------- -1.3225806 SELECT MONTHS_BETWEEN (TO_DATE('02-02-1995','MM-DD-YYYY'), TO_DATE('01-01-1995','MM-DD-YYYY') ) "Months" FROM DUAL; Months ---------- 1.03225806
Et vigtigt punkt at huske
MONTHS_BETWEEN beregner brøkdelen af antallet af måneder ved at antage, at
hver måned har 31 dage. Derfor tæller hver ekstra dag over en hel måned for 1/31 af en måned, og:
1 divideret med 31 =.032258065
Runde
Datofunktion | Beskrivelse |
RUNDE (x, datoformat) | Returnerer datoen 'x' afrundet til nærmeste århundrede, år, måned, dato, time, minut eller sekund som angivet af 'date_format'. |
Funktionen ROUND afrunder en datoværdi til den nærmeste dato som angivet af en formatmaske. Det er ligesom den standard numeriske ROUND-funktion, som afrunder et tal til det nærmeste antal med specificeret præcision, bortset fra at den fungerer med datoer
Eksempler
Select ROUND (TO_DATE ('12-MAR-2016'), 'MONTH') from dual; 01-MAR-2016 Select ROUND (TO_DATE ('17-MAR-2016'), 'MONTH') from dual; 01-APR-2016 select ROUND (TO_DATE ('01-MAR-2007'), 'YYYY') from dual; 01-JAN-2007 select ROUND (TO_DATE ('01-SEP-2007'), 'YEAR') from dual; 01-JAN-2008
Trunc
Datofunktion | Beskrivelse |
TRUNC (x, datoformat) | Returnerer datoen 'x' mindre end eller lig med det nærmeste århundrede, år, måned, dato, time, minut eller sekund som angivet af 'date_format'. |
Eksempler
Select TRUNC (TO_DATE ('12-MAR-2016'), 'MONTH') from dual; 01-MAR-2016 Select TRUNC (TO_DATE ('17-MAR-2016'), 'MONTH') from dual; 01-MAR-2016 select TRUNC (TO_DATE ('01-MAR-2007'), 'YYYY') from dual; 01-JAN-2007 select TRUNC (TO_DATE ('01-SEP-2007'), 'YEAR') from dual; 01-JAN-2007
Aritmetik med Oracle-dato
Vi kan udføre mange aritmetiske operationer på oracle-dato-datatypen. Vi kan tilføje eller trække et tal til eller fra en dato for en resulterende datoværdi. vi kan trække to datoer fra for at finde antallet af dage mellem disse datoer. vi tilføjer timer til dato ved at dividere antallet af timer med 24.
Eksempler på addition og subtraktion
SQL> select sysdate, sysdate+1/24, sysdate +1/1440, sysdate + 1/86400 from dual; SYSDATE SYSDATE+1/24 SYSDATE+1/1440 SYSDATE+1/86400 -------------------- -------------------- -------------------- -------------------- 01-Jul-2016 06:32:12 01-Jul-2016 07:32:12 01-Jul-2016 06:33:12 01-Jul-2016 06:32:13
Andre måder, vi kan bruge det på er
Beskrivelse | Datoudtryk |
Nu | Sysdato |
I morgen/ næste dag | Sysdato +1 |
Syv dage siden | SYSDATE -7 |
En time fra nu | SYSDATE + 1/24 |
Tre timer fra nu | SYSDATE + 3/24 eller SYSDATE + 1/8 |
En halv time fra nu | SYSDATE + 1/48 |
10 minutter fra nu | SYSDATE + 10/1440 |
30 sekunder fra nu | SYSDATE + 30/86400 |
Aritmetisk operation på datoforskel for at finde antallet af dage mellem dem
Vi kan trække to datoer fra for at finde dageforskellen mellem datoer
If the time part is same, then it will always whole number SELECT TO_DATE('25-MAR-2016 11:00:00 AM', 'DD-MON-YYYY HH:MI:SS AM') - TO_DATE('19-MAR-2016 11:00:00 AM', 'DD-MON-YYYY HH:MI:SS AM') diff_in_days FROM dual; DIFF_IN_DAYS ---------- 6 If the time part is not same, then it will always be having fractional components SELECT TO_DATE('25-MAR-2016 10:00:00 AM', 'YYYYMMDD HH:MI:SS AM') - TO_DATE('19-MAR-2016 11:00:00 AM', 'YYYYMMDD HH:MI:SS AM') diff_in_days FROM dual; DIFF_IN_DAYS ---------- 5.95833333 SQL> SELECT TO_DATE('25-MAR-2016 11:00:00 AM', 'YYYYMMDD HH:MI:SS AM') - TO_DATE('19-MAR-2016 10:00:00 AM', 'YYYYMMDD HH:MI:SS AM') diff_in_days FROM dual; DIFF_IN_DAYS ---------- 6.04166666
Vi kan finde Oracle-datoforskellen i måneder ved hjælp af forespørgslen
SELECT MONTHS_BETWEEN (TO_DATE('02-02-1995','MM-DD-YYYY'), TO_DATE('01-01-1995','MM-DD-YYYY') ) "Diff_in_Months", (TO_DATE('02-02-1995','MM-DD-YYYY')- TO_DATE('01-01-1995','MM-DD-YYYY') diff_in_days FROM DUAL;Diff_in_Months diff_in_days ---------------------------------------- 1.03225806 32
Vi kan også finde Oracle-datoforskellen i år ved at bruge forespørgslen
SELECT (TO_DATE('20130525', 'YYYYMMDD') - TO_DATE('20100101', 'YYYYMMDD')) diff_in_days , MONTHS_BETWEEN(TO_DATE('20130525', 'YYYYMMDD'), TO_DATE('20100101', 'YYYYMMDD')) Diff_in_months ,TRUNC(MONTHS_BETWEEN(TO_DATE('20130525', 'YYYYMMDD'), TO_DATE('20100101', 'YYYYMMDD'))) Diff_in_months_no_fraction, TRUNC(TRUNC(MONTHS_BETWEEN(TO_DATE('20130525', 'YYYYMMDD'), TO_DATE('20100101', 'YYYYMMDD'))) / 12) Diff_in_years_no_fraction ,MOD(TRUNC(MONTHS_BETWEEN(TO_DATE('20130525', 'YYYYMMDD'), TO_DATE('20100101', 'YYYYMMDD'))), 12) Diff_in_years_fraction_in_months FROM dual; DIFF_IN_DAYS DIFF_IN_MONTHS DIFF_IN_MONTHS_NO_FRACTION DIFF_IN_YEAR_NO_FRACTION DIFF_IN_YEARS_FRACTION_IN_MONTHS ____________________________________________________________________________________ 1240 40.7741 40 3 4
Håber du kan lide indlægget om oracle date datatype. Jeg har forsøgt at forklare forskellige ting som oracle-datofunktioner, oracle sql-datoformat, oracle sql-datosammenligning, oracle-datoforskel i år, oracle-datoforskel i dage, oracle-datoforskel i måneder. Det er ikke en komplet guide, men jeg har forsøgt at præsentere en masse nyttig information til oracle sql-udvikleren
Relaterede artikler
hvordan man skriver sql-forespørgsler
Oracle sql-vejledning:Grundlæggende SQL-sætning
Oracle sql-vejledning:Begrænsning af datasættet
Enkeltrække-funktioner i sql
Oracle sql-afkodningsbehandling
Download Oracle SQL-udvikler
https://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_commands_1029.htm#OLADM780