SQL Query data range limit - sql

I have this where SQL Query. I want to know if I can limit that user can only pick 2 days of of date range. meaning they cannot pick 1 month or 1 week or more than 2 days difference of querty data range.
WHERE
To_Date(to_char(B.time_stamp, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY')
and To_Date(to_char(B.rest_date, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')

If I understand your question, you are just asking how to limit the two dates so that they are within 2 days of each other. Date math is pretty simple in Oracle (which is my guess as to the DB you are using):
WHERE ABS(Date1 - Date2) <= 2
You don't need to convert it at all with to_char or anything else, since it is stored internally as an actual date. You can use this same type of logic to make sure it is less than 16 hours:
WHERE ABS(Date1 - Date2) <= 16/24
As long as you remember to adjust your units appropriately.
Note that in this case, 2 days means 48 hours. If you mean it has to be 2 actual days, then it is slightly different.

Related

Trying to accommodate relative defined date, such as 5 days ago, into my fixed date condition in PostgreSQL

I'm trying to condition my WHERE clause to accommodate relatively defined dates into my date filter. I'm pretty confused what type I need to use, if it's CONVERT or TO_DATE function, or if I need to put a CASE WHEN statement into my code.
This is the code that I have written so far:
WHERE event_create_verified_user_success.created_at_utc_date
BETWEEN DATE '2021-11-29' AND DATE '2021-12-05'
And this is the condition of the activity I need to finish:
If the desired date-period is not set manually using fixed dates like from “2021-11-29”
to “2021-12-05”, how would you change the where-clause to consider all data from relative
defined dates: “consider messages created between 10 days and 5 days ago (inclusive)”
I've only started PostgreSQL yesterday and the last time I've handle SQL was probably 4 years ago so I'm pretty confused at how much SQL has changed since then.
Thank you so much for helping!
The basic syntax hasn't really changed in the last 4 years (or even 15 years).
You can use current_date to obtain "today's date". You can subtract days from that
where ... between current_date - 10 and current_date - 5
If created_at_utc_date is a timestamp (= date and time) rather than a date (=date without time) it's better to use a range query though:
where created_at_utc_date >= current_date - 10
and created_at_utc_date < current_date - 4
Note the < combined with the next day you want to compare with.

Oracle Months Between does not work properly

Good morning,
I've wrote the following query to get the months difference between a date column (STRT_DT) and a timestamp column (VLD_FRM_TMS) stored in two different tables.
I don't know why it works for some records but does not for others (it calculates one month less)
select ID, floor (months_between (cast(a.VLD_FRM_TMS as date), STRT_DT)) as delta
from TABLE_A a
inner join TABLE_B b
on a.ID = b.ID
This is an example of record for which the calculation does not work:
VLD_FRM_TMS
-----------
28-FEB-21 12.00.00.000000000 AM
STRT_DT
--------
29-OCT-20
The formula calculates 3 months instead of 4...
Could anyone help me in locating the problem?
Thank you in advance
This is exactly the behavior that is described in the documentation:
If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer. Otherwise Oracle Database calculates the fractional portion of the result based on a 31-day month and considers the difference in time components date1 and date2.
(Note: Highlighting is mine.)
If you run this code:
select months_between(date '2021-02-28', date '2020-10-29') as delta
from dual
The result is 3.9677.
I suspect that you want some other logic. However, the question does not specify what logic you actually do want.
I actually want the months difference regardless of the specific day of the month.
You can truncate both values to the first of the month using the 'MM' format element, and then get the difference between those:
months_between (trunc(a.VLD_FRM_TMS, 'MM'), trunc(STRT_DT, 'MM')) as delta
That will now always be an integer - i.e. a whole number of months - so you don't need to trunc/floor/round the result.
db<>fiddle showing the problem with the old calculation and this version.

Modifying SYSDATE function

In one of my SQL queries, I am using
[... and z.READ_TIMESTAMP > TIMESTAMP_TO_EPOCH(TRUNC(SYSDATE-3)]
If I want the date to be exactly 5/31/2017, will I use 'SYSDATE' (date-n) function or some other expression? or how can a modify my query for 5/31/2017
If you want the date to be exactly 5/31/2017 then use TO_DATE() or TO_TIMESTAMP() depending on which data type you need (date or timestamp). As you are using SYSDATE already the the date data type should work.
-- e.g.
select
to_date('5/31/2017','mm/dd/yyyy')
, to_timestamp('5/31/2017','mm/dd/yyyy')
from dual
...
and z.READ_TIMESTAMP > TIMESTAMP_TO_EPOCH(to_date('5/31/2017','mm/dd/yyyy'))
HOWEVER
I suspect you may want more than just a way to establish a fixed date. For example are you asking for "how do I get that last day of the previous month?" which perhaps can be satisfied by using >= and the first day of current month like this:
...
and z.READ_TIMESTAMP >= TIMESTAMP_TO_EPOCH(trunc(sysdate,'MM'))
or if it really is the last day of the previous month can be achieved with a combination of LAST_DAY() and ADD_MONTHS()
and z.READ_TIMESTAMP >
TIMESTAMP_TO_EPOCH( last_day(add_months(trunc(sysdate,'MM'),-1)) )
Without knowing a great deal more about the nature of your data and query purpose please do note that each date you use when "truncated" also has the time set to 00:00:000 - so IF you data contains time within a day other than 00:00:00 then these 2 queries might NOT produce the same result
.... datetimecolumn > to_date('05/31/2017','mm/dd/yyyy') -- "a"
.... datetimecolumn >= to_date('06/01/2017','mm/dd/yyyy') -- "b"
For example "a" the entire 24 hour duration of 05/31/2017 would be included in the results, but for example "b" that same 24 hour duration would be excluded from results. In my experience the last day of any month isn't really the best method for locating date/time based data, instead usually it is the first day of the next month that produces the correct result.

SQL searching in 2 week interval from the current date

I'm having trouble setting up a SQL to bring up all information 2 weeks before and after the current date. Here is what I am currently doing:
Select WRK.Wrk, WRK.Client, WRK.Status, WRK.TAT, WRK.Due
From WRK
WHERE WRK.Due >= now()
Order By WRK.Due Desc, WRK.Status Desc
This gets me everything due on or after the current date but when I try to add lines to indicate 2 weeks before and after the current date I get errors.
Thanks
Date/time function vary significantly among databases. The use of now() makes me think of MySQL. The syntax in MySQL is:
where wrk.Due between date_sub(curdate(), interval 2 weeks) and date_add(curdate, interval 2 weeks)
Note that between includes the end dates, so this might be off by a day in either direction.
You can implement similar logic in other databases, but the specific functions would look different.

Business Week logic in Oracle SQL

I am using the following Oracle SQL query to work out if a week is more than 6 business weeks ago.
,CASE
WHEN to_char(next_day(CURRENT_TIMESTAMP,'sunday'),'iw')-6 <= to_char(next_day(m.COMPLETED_DT,'sunday'),'iw') THEN 'Yes'
ELSE 'No' END AS "Completed.Prior 6 Weeks"
The trouble is that this statement does not take into account the year, so now it is 2015, the business week is 1 and everything in the previous year has a greater business week.
I some how need to take into account the year as well, something like the below kind of works, but doesn't take into consideration the Business Week.
CURRENT_TIMESTAMP -42 >= m.COMPLETED_DT
Any help greatly appreciated
Rather than using TO_CHAR() to get the business week (which I think means the week starting on Monday), you should use TRUNC() - this way the year is preserved:
, CASE WHEN TRUNC(NEXT_DAY(SYSDATE, 'sunday'), 'iw') - 42 >=
TRUNC(NEXT_DAY(m.COMPLETED_DT, 'sunday'), 'iw') THEN 'Yes'
ELSE 'No' END AS "Completed.Prior 6 Weeks"
Note that I used 42 instead of 6 as Oracle date arithmetic uses days.
I'm not sure I see an advantage to using CURRENT_TIMESTAMP over SYSDATE. If you want to use the ANSI standard, you would want CURRENT_DATE ... I don't think you need the granularity of CURRENT_TIMESTAMP here, especially since you're truncating it. Also, you had <= when I think you mean >= (from what you have later in the question).