SQL query date range - sql

I have the following table:
ID DATE_START DATE_END
------- ---------- --------
11944 10.01.15 20.01.15
I would like to select rows based an a date range, e.g
01.01.15 - 25.01.15
15.01.15 - 25.01.15
In both cases I would like to select the column mentioned above. Is this possible with SQL? I tried a few things but i don't get the second query working. I use Oracle DB:
Example usage:
I want to query ma datatable like this: Show me all Entries between 15.01.15 and 25.01.15. This should yield to row with ID 11944

You want to return a row if two periods overlap, assuming both columns are defined as DATE.
select *
from tab
where DATE_START <= DATE '2015-01-25' -- end of searched period
and DATE_END >= DATE '2015-01-15' -- begin of searched period
In Standard SQL there's an OVERLAPS predicate which is not (officially) supported by Oracle:
where (DATE_START, DATE_END) OVERLAPS (DATE '2015-01-15', DATE '2015-01-25')

Related

oracle query to extract all the dates within given periods and range

Consider if there is a table with two column
TABLE TIME_FRAME
------------------------
|FROM |TO |
|2013-12-13 |2014-01-06|
|2011-12-05 |2011-12-31|
|2014-01-23 |2014-02-22|
|2011-11-21 |2011-12-17|
........
FROM and TO from each row defines a period of time. Also there can be overlap between the periods (here row 2 and row 4) or cover multiple periods
if give a start_date and end_date as parameters here the requirement is about return all the dates falls within the parameters and also within any of the periods in the columns
for example
if start_date is 2013-12-25 and end_date is 2014-02-10
so from above data it should return all dates between
`2013-12-25` and `2014-01-06`
plus
`2014-01-23` and `2014-02-10`
is it possible to create a query for above requirement (not by PL/SQL)?
It's possible by creating set of days using LEVEL recursion operator and then filtering this set by comparing it to your table data. Here is the working Oracle SQL query for you:
select day
from (select to_date('25-DEC-2013', 'dd-mon-yyyy') - 1 + level day
from dual
connect by level <= to_date('10-FEB-2014', 'dd-mon-yyyy') -
to_date('25-DEC-2013', 'dd-mon-yyyy') + 1)
where exists
(select 1 from TIME_FRAME p where day between p.FROM and p.TO);
Hope this helps!

Sql query for date range for individual date values

My question is specific to my problem at hand, so I would try to explain the scenario first. I need to write a sql query. Following is the scenario:
Table columns for table1:
effective_date
expire_date
amount_value
state_id
amount_entry_type
Case 1, Input values:
input_date
I've achieved it using following sql query:
Sample Query:
select state_id, sum(amount)
from table1
where state_id=3 and (input_date between effective_date and expiry_date)
group by state_id;
My Question:
Now I've a date range and I wish to achieve the above for all the dates between date range.
Input values 2:
input_start_date
input_end_date
Expected Output:
Find the sum of amount_value grouped by states where input_date between effective and expire_date for input_date between input_start_date and input_end_date.
So the query would give following sample result for date range 2016-07-07 and 2016-07-08 :
state amount_sum date
California 100 2016-07-07
Florida 200 2016-07-08
I'm using postgres as database and django for querying and processing the result.
Options:
1. Fetch all the data and process using python.
2. Loop over given date range and fire the query above as:
for input_date in date_range(input_start_date, input_end_date):
//Execute above query
Both above solutions might have performance issues so I was wondering if I could achieve it using single sql query.
You can indeed do this with a single query, using the generate_series() set-returning-function to make the list of days. If you are sure that all dates have corresponding rows for the state then you can you use a regular JOIN, otherwise use a LEFT JOIN as below.
SELECT state_id, sum(amount), dt AS "date"
FROM generate_series(input_start_date, input_end_date, '1 day') dates(dt)
LEFT JOIN table1 ON state_id = 3 AND (dt BETWEEN effective_date AND expiry_date)
GROUP BY state_id, dt;

SQL: select datetime values prior to that date based on it's value

I want to select rows for a field MRD which is declared as date where it is prior for that date only.
So
(case when sum (transPoints) > 4 and MRD is that same date then 4
So if a row has a date of today, I want the case when to be triggered when the transaction points are bigger than 4 against all columns with the same date.
As you can imagine the date field will be different against many rows.
Based on what I can understand from your question, it seems that the GROUP BY clause may be what you're looking for. If your date column is in the correct format then you may have to use something like:
SELECT CAST(DateColumn as DATE)
FROM YourTable
GROUP BY CAST(DateColumn as DATE)

Days_Between two dates

I would like to ask how do i check if the difference between two dates.
BillingDate which is a date type with an entry 'DD-MON-YYYY'
and the other date is the current date.
sys_date - BillingDate = daysFromBilled
alot of the examples i find they actually stated the second date to calculate the difference but what i am looking for is the difference between the current date so i can add it into a schedule or job.
i am using oracle btw.
Another point to add, i will continue to search, but if your could also recommend, how should i implement such a function:
Calculate date difference from all BillingDate entries
To trigger an alter table if the difference is more than 30 days to put Status as Late.
If Status is more than 60 days the Service attribute will be altered and changed to Cut
here is my rough table layout
Cust Billing
-------- ----------
CustID(PK) BillingID(PK)
LateStatus LateStatus
Service BillingDate
CustID
Thanks alot.
Update
REPLACE view DateDifference as
select trunc(sysdate)- trunc(BillingDate)
from Billing;
seems legit.
Simply subtract one date from the other:
BillingDate - sysdate
To do that in a select statement, just use it like this:
select billingdate - sysdate as daysFromBilled
from ...
Inside a trigger you use a regular assignment operator:
declare
daysFromBilled integer;
begin
daysFromBilled := :new.billingdate - sysdate;
...
that will return the number of days, including fractional values if the time is different (a DATE column in Oracle also contains a time!).
If you only want to get full days, use this:
trunc(BillingDate) - trunc(sysdate)
This statement of yours:
date type with an entry 'DD-MON-YYYY'
Indicates a misunderstanding on how DATE values work.
A DATE (or TIMESTAMP) does not have any format.
They are stored in binary form in your column. The format is only applied when you display the value and thus convert it to a character literal. That is the work of the client application you use to display the values. SQL*Plus uses the NLS settings, other SQL tools might use a different configuration.
All customers:
SELECT CUSTID
FROM BILLING
WHERE (SYSDATE - Billing_Date) >= 60
;
The following statement should update all the customer records where the difference is 60 days and over. Also, have added a clause to check if the service is already not set to CUT previously, so you don't end up updating the same records everytime.
UPDATE CUST_TABLE
SET SERVICE = 'CUT'
WHERE CustID in ( SELECT CustID
FROM BILLING_TABLE
WHERE (Sysdate - Billing_Date) >= 60
)
AND NVL(SERVICE, 'X') != 'CUT'
;

issue with complex query involving returning 0 for no data in query result

I have a table defined in Oracle11g schema like this
Txn_summ_dec
=================
id
currentdate
resource_id
user_id
trans_id
eventdescptn
each resource has different event descriptions.
I give a date range (of maximum 1 month or less) and resource_id and I want to get distinct count of all users for the given resource id, group by currentdate, eventdescptn
So I have the following query
SELECT COUNT(DISTINCT(txn_summ_dec.user_id)) as dusers, currentDate, eventdescptn
FROM Txn_summ_dec
WHERE resource_id = 1
AND currentdate BETWEEN TO_DATE('2011-12-01', 'YYYY-MM-DD')
AND TO_DATE('2011-12-31', 'YYYY-MM-DD')
GROUP BY currentdate, eventdescptn
and it gives me rightly the result below
dusers currentdate eventdescptn
182 12/01/2011 00:00:00 Save
33 12/04/2011 00:00:00 Save
98 12/01/2011 00:00:00 Read
22 12/30/2011 00:00:00 Write
I want result in the following format: From the query
with the given date range is suppose 5th to 5th of a month (or less) I want results for all dates in the range for all eventdescptn of a resource. If there is no result for a particular date in the range, for a particular event descptn then it should still have that record in the resultset with a 'dusers' value = 0
so if a resource has 3 different eventdescptns (Save, Read, Write) and the date range is 5th to 30th of a month then there should be a total of 26X3 = 78 records in the resultset..
How do I write a query for that?
Also I will need to convert it to hibernate later.. but Sql to start with is fine
Thanks in advance
Check the accepted answer here:
generate days from date range
If I understand you correctly you don't necessarily have an event for every date in the range in your log. That answer gives you a way to materialize a list of dates in the range. If you can modify it to include 1 of each of those dates per event, you would just have to join back to the results you have already aggregated here and set the null dUsers to zero.
I haven't tried this, but I wonder if you could you do:
WITH the_query AS (
... your query here ...
)
SELECT dusers, currentdate, eventdescptn
FROM the_query
WHERE 0 != ( SELECT COUNT(*) FROM the_query )
UNION
SELECT 0, NULL, NULL
FROM the_query
WHERE 0 = ( SELECT COUNT(*) FROM the_query )