Good day,
Give me advice,please,
How can i replace this Oracle syntax:
sum(fact) over(partition by name order by rep_date range between interval '20' month preceding and current row) as w_sum
to use it in Hive? I have a mistake related with interval '20'
Convert the rep_date into seconds since Unix epoch using unix_timestamp and then calculate the seconds for 20 months and use it in the range,between. Hive does not support specifying interval type in range.
sum(fact) over(
partition by name
order by unix_timestamp(rep_date,'MM-dd-yyyy') -- Specify the rep_date format here
range between 51840000 preceding and current row) as w_sum
Related
I want to SELECT a TIMESTAMP(6) with milliseconds, but at the same time I need to subtract 3 hours (0.125 of a day) from that TIMESTAMP to convert it to my timezone. So I tried:
SELECT To_Char(UTCSCANTIME-0.125,'YYYY-MM-DD HH24:MI:SS') AS LOCALSCANTIME
Outcome: 2018-08-01 19:22:39
If I append "FF" to show milliseconds:
SELECT To_Char(UTCSCANTIME-0.125,'YYYY-MM-DD HH24:MI:SS.FF') AS LOCALSCANTIME
Outcome: ORA-01821: date format not recognized
However if I keep the "FF" but I don't subtract 0.125:
SELECT To_Char(UTCSCANTIME,'YYYY-MM-DD HH24:MI:SS.FF') AS LOCALSCANTIME
Outcome: 2018-08-01 22:22:39.259000
How can I achieve both things?
Thanks in advance!
Subtract a 3 hour INTERVAL instead of 0.125.
SELECT To_Char(UTCSCANTIME-INTERVAL '3' HOUR,'YYYY-MM-DD HH24:MI:SS.FF') AS LOCALSCANTIME
Subtracting a number like 0.125 implicitly converts the result to a DATE, losing your fractional seconds.
Also, note, there are better ways in Oracle to convert time zones than to add and subtract intervals.
I am trying to add a day with a specific date using add_months in oracle database.
I wrote this line:
SELECT ADD_MONTHS('01-JAN-2018', MONTHS_BETWEEN('02-JAN-2018', '01-JAN-2018')) FROM DUAL;
this returns:
01-JAN-18
Why doesn't it return 02-JAN-18?? Can I add one day to the date using this function?
Why doesn't it return 02-JAN-18??
According to MONTHS_BETWEEN documentation,
The MONTHS_BETWEEN function calculates the number of months between
two dates. When the two dates have the same day component or are both
the last day of the month, then the return value is a whole number.
Otherwise, the return value includes a fraction that considers the
difference in the days based on a 31-day month
So,
select MONTHS_BETWEEN('02-JAN-2018', '01-JAN-2018') FROM DUAL ;
yields
.0322580645161290322580645161290322580645
ADD_MONTHS returns the date date plus integer months.
So, .0322.. is considered as integer 0 and your query is equivalent to
SELECT ADD_MONTHS('01-JAN-2018', 0) FROM DUAL;
In order to add 1 months, simply take the difference of two dates.
SELECT ADD_MONTHS(DATE '2018-01-01', DATE '2018-01-02' - DATE '2018-01-01') FROM DUAL;
Or better, add an INTERVAL of 1 month
SELECT DATE '2018-01-01' + INTERVAL '1' MONTH FROM DUAL;
To answer your question, add 1 day, simply use
SELECT DATE '2018-01-01' + 1 FROM DUAL;
Can someone explain me what does the below oracle query do and what is it's output?
select unique trunc(sysdate-370 + level, 'IW') AS datetime from dual
connect by level <= 360 order by datetime;
select sysdate-370 + level AS datetime
from dual
connect by level <= 360;
Will generate 360 rows starting with the current date/time minus 370 days plus one day per row. So rows between 369 and 10 days before the current date/time.
TRUNC( datetime, 'IW' ) will truncate the date to the start of the ISO week (midnight on Monday of that week - irrespective of the NLS settings for date language and/or territory that affect some other options for truncating dates). So you will end up with duplicate rows for each generated row that is in the same week.
The UNIQUE keyword will get rid of those duplicate rows.
The order by datetime will order the results in ascending date order - however, the rows are generated in ascending order so this clause is unnecessary.
So the output will be 52 or 53 rows (depending on what the current day of the week is) starting with Monday midnight of each week containing the date 369 days before the current day up until the week containing 10 days before the current date.
The output (when run on 13th September 2017) is 52 rows (I skipped a few):
05-SEP-2016
12-SEP-2016
19-SEP-2016
26-SEP-2016
03-OCT-2016
...
31-JUL-2017
07-AUG-2017
14-AUG-2017
21-AUG-2017
28-AUG-2017
According to documentation trunc(dateval, 'IW') truncates to:
Same day of the week as the first day of the calendar week as defined by the ISO 8601 standard, which is Monday
connect by level <= N is a trick for producing a set of N rows with level values from 1 to N.
I need to query 2 tables, one contains a TIMESTAMP(6) column, other contains a DATE column. I want to write a select statement that prints both values and diff between these two in third column.
SB_BATCH.B_CREATE_DT - timestamp
SB_MESSAGE.M_START_TIME - date
SELECT SB_BATCH.B_UID, SB_BATCH.B_CREATE_DT, SB_MESSAGE.M_START_TIME,
to_date(to_char(SB_BATCH.B_CREATE_DT), 'DD-MON-RR HH24:MI:SS') as time_in_minutes
FROM SB_BATCH, SB_MESSAGE
WHERE
SB_BATCH.B_UID = SB_MESSAGE.M_B_UID;
Result:
Error report -
SQL Error: ORA-01830: date format picture ends before converting entire input string
01830. 00000 - "date format picture ends before converting entire input string"
You can subtract two timestamps to get an INTERVAL DAY TO SECOND, from which you calculate how many minutes elapsed between the two timestamps. In order to convert SB_MESSAGE.M_START_TIME to a timestamp you can use CAST.
Note that I have also removed your implicit table join with an explicit INNER JOIN, moving the join condition to the ON clause.
SELECT t.B_UID,
t.B_CREATE_DT,
t.M_START_TIME,
EXTRACT(DAY FROM t.diff)*24*60 +
EXTRACT(HOUR FROM t.diff)*60 +
EXTRACT(MINUTE FROM t.diff) +
ROUND(EXTRACT(SECOND FROM t.diff) / 60.0) AS diff_in_minutes
FROM
(
SELECT SB_BATCH.B_UID,
SB_BATCH.B_CREATE_DT,
SB_MESSAGE.M_START_TIME,
SB_BATCH.B_CREATE_DT - CAST(SB_MESSAGE.M_START_TIME AS TIMESTAMP) AS diff
FROM SB_BATCH
INNER JOIN SB_MESSAGE
ON SB_BATCH.B_UID = SB_MESSAGE.M_B_UID
) t
Convert the timestamp to a date using cast(... as date). Then take the difference between the dates, which is a number - expressed in days, so if you want it in minutes, multiply by 24*60. Then round the result as needed. I made up a small example below to isolate just the steps needed to answer your question. (Note that your query has many other problems, for example you didn't actually take a difference of anything anywhere. If you need help with your query in general, please post it as a separate question.)
select ts, dt, round( (sysdate - cast(ts as date))*24*60, 2) as time_diff_in_minutes
from (select to_timestamp('2016-08-23 03:22:44.734000', 'yyyy-mm-dd hh24:mi:ss.ff') as ts,
sysdate as dt from dual )
;
TS DT TIME_DIFF_IN_MINUTES
-------------------------------- ------------------- --------------------
2016-08-23 03:22:44.734000000 2016-08-23 08:09:15 286.52
I have a table A which contains a Date type attribute. I want to write a query to select the date in another table B with value one month after the value in A.Any one know how to do it in oracle?
uhm... This was the first hit on google:
http://psoug.org/reference/date_func.html
It seems you're looking for the "add_months" function.
You need to use the ADD_MONTHS function in Oracle.
http://www.techonthenet.com/oracle/functions/add_months.php
Additional info: If you want to use this function with today's date you can use ADD_MONTHS(SYSDATE, 1) to get one month from now.
The question is to select a date_field from table b where date_field of table b is one month ahead of a date_field in table a.
An additional requirement must be taken into consideration which is currently unspecified in the question. Are we interested in whole months (days of month not taken into consideration) or do we want to include the days which might disqualify dates that are one month ahead but only by a couple of days (example: a=2011-04-30 and b=2011-05-01, b is 1 month ahead but only by 1 day).
In the first case, we must truncate both dates to their year and month values:
SELECT TRUNC( TO_DATE('2011-04-22','yyyy-mm-dd'), 'mm') as trunc_date
FROM dual;
gives:
trunc_date
----------
2011-04-01
In the second case we don't have to modify the dates.
At least two approaches can be used to solve the initial problem:
First one revolves around adding one month to the date_field in table a and finding a row in table b with a matching date.
SELECT b.date_field
FROM tab_a as a
,tab_b as b
WHERE ADD_MONTHS( TRUNC( a.date_field, 'mm' ), 1) = TRUNC( b.date_field, 'mm' )
;
Note the truncated dates. Leaving this out will require a perfect day to day match between dates.
The second approaches is based on calculating the difference in months between two dates and picking a calculation that gives a 1 month difference.
SELECT b.date_field
FROM tab_a as a
,tab_b as b
WHERE months_between( TRUNC( b.date_field, 'mm') , TRUNC(a.date_field, 'mm') ) = 1
The order of the fields in months_between is important here. In the provided example:
for b.date_field one month ahead of a.date_field the value is 1
for b.date_field one month before a.date_field the value is -1 (negative one)
Reversing the order will also reverse the results.
Hope this answers your question.