SQL - filter values based on month & date - sql

I'm currently strugeling to get something done.
I needed only the rows where the date is between a certain date and month.
Example show only the rows where the date is between 01/05 (DD/MM) and 08/07 (DD/MM) the date can be found in the table tasks within the field information.
The year can't make any sense, but the results may only between those two dates in that year.
I've tried:
BETWEEN (TO_DATE ('01/05','DD/MM') AND (TO_DATE('08/07', 'DD/MM')
EXTRACT (DD/MM) from information.
none of those are working for me, I hope that someone of you can help me to figure this out!.
Thanks!

You seem to want to disregard the year. If so, then I would recommend:
TO_CHAR(datecol, 'MM/DD') BETWEEN '05/01' AND '07/08'
In order for BETWEEN to work in this case, you need the format in the order of MM-DD.
If you want this for a particular year, then use direct date comparisons:
datecol >= DATE '2018-05-01' AND
datecol < DATE '2018-07-09' -- note this is one day later
Oracle dates have a time component, so you need to be careful when making comparisons.

Related

First day of the month

WHERE to_date(smz_loanservicing.as_of_date) = last_day(add_months(current_date, -1))
The above will provide data only if the loanservicing.as_of_date occurs on the very last day of the month.
Last month (May 31 2020) the last day of the month fell on Sunday.
Is there a way to get the the first day of the month and say if this particular date occurs between the first and last day of the month, show the date? Essentially there were no activities on Sunday so the data was missed.
I tried
to_date(smz_loanservicing.as_of_date)
between first_day(add_month(current_date,-1))
and last_day(add_months(current_date, -1))`
However I get syntax error.
You seem to want to check if your date column belongs to the current month.
The syntax you use would work in Oracle, so let me assume this is the database that you are running. I also assume that column as_of_date is of datatype date (or timestamp).
What you ask for should be as simple as:
where
as_of_date >= trunc(current_date, 'mm')
and as_of_date < add_months(trunc(current_date, 'mm'), 1)
Actually, your syntax would also work in Snowflake - and so would the above code.
Note: if as_of_date actually is a string, then you need to_date() to convert it.
You could just truncate the date to the month, then you don’t need the know the first or last day.
where trunc(as_of_date, ‘MM’) = trunc(current_date, ‘MM’)

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.

How to get records between from and to date, when dates are for the same month/year?

I am trying to create a query to that can get some records in a table that is between a from and to date, with the dates being in month/year only. The problem that I am having is trying to get the records when the from and to dates are for the same month/year.
Here is a example of the issue that I am having:
select start_date
from job
where trunc(start_date) between to_date('05-2016','mm-yyyy') and to_date('05-2016','mm-yyyy')
In the job table, there are records with start_date in the month of May, but in order to see them I need to set the to date to '06-2016'. Is there way to get all of the records with a start_date in the month of May by just specifying that the from and to dates is 05-2016?
In your example you are selecting all start_date's between 5/1/2016 and 5/1/2016.
It seems like you want to capture everything in a month, but you are not specifying a format to truncate. Without specifying 'Month' in the Trunc() you are truncating to the day. When you truncate to Month you can now, actually just set it equal to the to_date() rather than between:
select start_date
from job
where trunc(start_date,'Month') = to_date('05-2016','mm-yyyy')
Here is some information on Trunc(date, [fmt]). when the fmt argument is left blank Trunc() defaults to 'round' to the nearest day but there are many other options.
If you want to specify ranges greater than a Month you can use between (but note, this is from the first day of the first to_date() to the first day of the second 'to_date()':
select start_date
from job
where trunc(start_date)
between to_date('06-2016','mm-yyyy')
and to_date('09-2016','mm-yyyy')
In this example all Start_dates would populate between 6/1/2016 and 9/1/2016.
I think the most accurate way to do this would be:
select start_date
from job
where trunc(start_date)
between to_date('06-01-2016','mm-dd-yyyy')
and to_date('09-30-2016','mm-dd-yyyy')
How about?
select start_date
from job
where trunc(start_date, 'mm') between
to_date('05-2016', 'mm-yyyy')
and to_date('05-2016', 'mm-yyyy')
Oracle has no way of interpolating the date on the right end of your between as falling at the end of the month. When to_date() is missing a day value in the format it simply supplies the 1st as the default value. Not sure if that's the behavior your were anticipating.
If instead you truncate dates by month (rather than day) then the comparisons will only involve dates falling on the first of the month. With the dates collapsed that way you can then treat a start and end of the two identical values as an inclusive range. Presumably you'll replace the hard-coded dates with parameters of some form and this works for wider ranges as well. Of course, the between can be just an equality test if you're always querying on a single month. And this isn't going to use an index on your column so it's not necessarily the most efficient.
I think this is what you're looking for. Is there a reason you need to supply the date value(s) in that format? Perhaps there's a better way to approach this using a little date math.
Try like this:
select start_date
from job
where trunc(start_date) between to_date('05-2016','mm-yyyy')
and dateadd('d', -1, dateadd('m', 1, to_date('05-2016','mm-yyyy')))
In order to see an entire month worth of dates, your date range in the between clause must be a full month long.

Group Dates by month

I've been working on this query and I'm about 90% where I need to be however there is one piece of this that I'm unable to figure out. Basically I'm looking for the Sum of Net flows by month, starting 12/31/2014 through the current date. I'm able to extract data by day and the sum of net flows for that day, however now I really need to be able to group all the dates in to their respective months. Ex. If I have 01/01/2015, 01/02/2015 and 01/03/2015 I just want both of them to be grouped together and show up as 01/2015. Bellow is the query that I have written. Please help with this last step.
SELECT
DATE,
SUM(NET_FLOWS/1000000.00) AS YTD_NET_FLOWS
FROM
HISTORY_TBL
WHERE
DATE >= TO_DATE ('12312014','MMDDYYYY')
GROUP BY
DATE
ORDER BY
DATE
You can truncate a date to a given format (day, year, month, etc.), as shown here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
SELECT TRUNC(DATE,'MM'), SUM(NET_FLOWS/1000000.00) AS YTD_NET_FLOWS
FROM HISTORY_TBL
WHERE DATE >= TO_DATE ('12312014','MMDDYYYY')
GROUP BY TRUNC(DATE,'MM')
ORDER BY DATE

SQL Query to Count Number of Days, Excluding Holidays/Weekends

I have a "workDate" field and a "receivedDate" field in table "tblExceptions." I need to count the number of days beteen the two. workDate always comes first - so, in effect, it's kind of like workDate is "begin date" and receivedDate is "end date". Some exclusions make it tricky to me though:
First, I need to exclude holidays. i do have a table called "tblHolidays", with one field - holidayDate. I have holidays stored up through next year, so maybe I can incorporate that into the query?
Also, most flummoxing is that work dates can never occur on weekends, but received dates can. So, i somehow need to exclude weekends when i'm counting, but allow for a weekend if the received date happens to fall on a saturday or sunday. so, if the work date is June 3rd, 2011, and received date is June 11th, 2011, the count of valid days would be 7, not 9.
Any help on this is much appreciated. Thanks!
Something like this should give you the number of days with the holidays subtracted:
select
days = datediff(day, workDate, receivedDate)
- (select count(*) from tblHolidays where holidayDate >= workDate and holidayDate < receivedDate)
from
tblExceptions
Note that the date functions differ between database systems. This is based on MS SQL Server, so it may need adapting if you are using some other database.
If you have a table full of dates to include (non-weekends, non-holidays, etc.) and you knew when the 'begin' date and the 'end' date is, then you can do something roughly like this:
select count(*) from tblIncludedDates where beginDateValue <= dateField and endDateValue >= dateField
to get the number of valid days between those dates.