Return records between now and previous week - sql

I have the following SQL query in oracle:
SELECT * FROM
(
SELECT s.singleid,s.titel,a.naam,s.taal,SUM(b.aantal) AS "AANTAL VERKOCHT"
FROM singles s
JOIN artiesten a on a.artiestid = s.artiestid
JOIN bestellingen b on b.singleid = s.singleid
GROUP BY s.singleid,s.titel,a.naam,s.taal,b.datum
ORDER BY sum(b.aantal) DESC
)
WHERE ROWNUM <= 5
This works, but I need to return only the records where b.datum is between the time now, and previous week.
How do I do this?

You should be able to add a BETWEEN clause to your where:
WHERE b.datum between SYSDATE - 6 AND SYSDATE

You would want to extract from the BESTELLINGEN table only those rows where [datum] is greater than or equal to (today at midnight minus 7 days) and less than or equal to 'now' (or less than tomorrow at midnight, according to your requirement). I would probably make this set of Bestellingen rows an inline view and join the other tables to it, and then do your grouping.

In SQL Server the syntax is:
AND (b.datum > DATEADD(week, -1, GetDate()) and b.datum < GetDate())
I would assume the syntax is the same, or very similar, in Oracle.

Related

SQL if statement for date range

Hi I was needing help with the syntax to add a condition where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month. Is it something you can help with please? Below is how my query is structured.
Select *
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Select *,
CASE WHEN day(GETDATE()) > 5 THEN GETDATE()
ELSE DATEADD(month,-1,getdate()) END as date
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Based on a vague description of your problem this is the best I can write.
If you simply want to include todays date (or the same date from last month if it's currently the 5th or earlier in the current month), then this can be done in your SELECT clause:
select
case
when datepart(day,getdate()) <= 5
then dateadd(month,-1,getdate())
else getdate()
end
If you want to actually use this date to compare to some field in your dataset, then you can include this same case expression in your WHERE clause.
where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month.
Based on this description, you want something like this:
select *
from table1 e left join
table2 d
on e.ENTITY_NBR = d.entity_nbr and
(day(getdate() > 5 and datediff(month, d.date_col, getdate()) = 0 or
day(getdate() <= 5 and datediff(month, d.date_col, getdate()) = 1)
)

Using the result of a SQL subquery in multiple joins

I have a subquery :-
SELECT TOP 1 Months.EndDate
FROM (SELECT TOP 1 *
FROM FinancialMonth
WHERE FinancialMonth.EndDate > DATEADD(MONTH, -12, GETDATE())
AND FinancialMonth.StartDate < GETDATE()
ORDER BY Period ASC) Months
ORDER BY Months.Period DESC
This returns the Month End Date and works for any number of months ago in the last year simply by changing the second TOP 1.
My problem is that I need to use this date in a number of LEFT JOIN statements where I compare it to two tables. I also need to return it in the final SELECT SUM statement.
By manually inputting the date to the LEFT JOIN queries I can run the main query and have a result back in under 1 second. However if I place this subquery against each LEFT JOIN it can take well over a minute to run. Given that I would like to run this query for each of the last 12 months this is going to tie the server up for an unacceptable amount of time.
Is there any way of running a query and then referencing this result within the LEFT JOIN subqueries without it running over and over. At present it appears to running well over 100k times.
Already i dont understand why you use 2 x top 1 (a top 1 in top 1 give 1 row), you query can be simplify to :
SELECT TOP 1 EndDate
FROM FinancialMonth
WHERE FinancialMonth.EndDate > DATEADD(MONTH, -12, GETDATE())
AND FinancialMonth.StartDate < GETDATE()
ORDER BY Period ASC
Now for what you want you can do Something like that:
with TblEndDate as (
SELECT TOP 1 EndDate
FROM FinancialMonth
WHERE FinancialMonth.EndDate > DATEADD(MONTH, -12, GETDATE())
AND FinancialMonth.StartDate < GETDATE()
ORDER BY Period ASC
)
select * from othertable f1
left outer join TblEndDate f2 on f1.DateInOthertable>=f2.EndDate

Records 1 Hour Before and 1 Hour After

I have a table with a set of trouble ticket data. I would like to write a query that selects all the records in this table that have occurred from 1 hour before to 1 hour after a particular record was inserted.
Example:
Error "xyz" occurred at 2018-01-03 15:30:06.000
I would like to return EVERY trouble ticket that was created between 14:30:06.000 and 16:30:06.000 on 2018-01-03. I would like this to happen for all occurrences of that error since the beginning of the year.
Is this possible?
This is what I have, considering the example provided below. I'm still only returning the results in the temp table, and not the +1h and -1h of records from the original table.
select * into #temp
from Incident
where INCIDENT_REPORTED_DATE_TIME > '01/01/2018'
and SUMMARY like '%error%'
select i.*
from Incident i
join #temp t on i.INCIDENT_ID = t.INCIDENT_ID
where i.INCIDENT_REPORTED_DATE_TIME >= DATEADD(HH, -1, t.INCIDENT_REPORTED_DATE_TIME)
and i.INCIDENT_REPORTED_DATE_TIME < DATEADD(HH, 1, t.INCIDENT_REPORTED_DATE_TIME)
order by i.INCIDENT_REPORTED_DATE_TIME
Here is an ANSI SQL approach:
select t.*
from t join
t t2
on t2.col = 'xyz' and
t.created >= t2.created - interval '1 hour' and
t.created <= t2.created + interval '1 hour'
order by t.created;
Note that the exact syntax varies by database (which isn't specified as I write this). But this idea should work in almost any database, with the right date/time functions.
EDIT:
In SQL Server, this looks like:
select t.*
from t join
t t2
on t2.col = 'xyz' and
t.created >= dateadd(hour, -1, t2.created) and
t.created <= dateadd(hour 1, t2.created)
order by t.created;

Add one for every row that fulfills where criteria between period

I have a Postgres table that I'm trying to analyze based on some date columns.
I'm basically trying to count the number of rows in my table that fulfill this requirement, and then group them by month and year. Instead of my query looking like this:
SELECT * FROM $TABLE WHERE date1::date <= '2012-05-31'
and date2::date > '2012-05-31';
it should be able to display this for the months available in my data so that I don't have to change the months manually every time I add new data, and so I can get everything with one query.
In the case above I'd like it to group the sum of rows which fit the criteria into the year 2012 and month 05. Similarly, if my WHERE clause looked like this:
date1::date <= '2012-06-31' and date2::date > '2012-06-31'
I'd like it to group this sum into the year 2012 and month 06.
This isn't entirely clear to me:
I'd like it to group the sum of rows
I'll interpret it this way: you want to list all rows "per month" matching the criteria:
WITH x AS (
SELECT date_trunc('month', min(date1)) AS start
,date_trunc('month', max(date2)) + interval '1 month' AS stop
FROM tbl
)
SELECT to_char(y.mon, 'YYYY-MM') AS mon, t.*
FROM (
SELECT generate_series(x.start, x.stop, '1 month') AS mon
FROM x
) y
LEFT JOIN tbl t ON t.date1::date <= y.mon
AND t.date2::date > y.mon -- why the explicit cast to date?
ORDER BY y.mon, t.date1, t.date2;
Assuming date2 >= date1.
Compute lower and upper border of time period and truncate to month (adding 1 to upper border to include the last row, too.
Use generate_series() to create the set of months in question
LEFT JOIN rows from your table with the declared criteria and sort by month.
You could also GROUP BY at this stage to calculate aggregates ..
Here is the reasoning. First, create a list of all possible dates. Then get the cumulative number of date1 up to a given date. Then get the cumulative number of date2 after the date and subtract the results. The following query does this using correlated subqueries (not my favorite construct, but handy in this case):
select thedate,
(select count(*) from t where date1::date <= d.thedate) -
(select count(*) from t where date2::date > d.thedate)
from (select distinct thedate
from ((select date1::date as thedate from t) union all
(select date2::date as thedate from t)
) d
) d
This is assuming that date2 occurs after date1. My model is start and stop dates of customers. If this isn't the case, the query might not work.
It sounds like you could benefit from the DATEPART T-SQL method. If I understand you correctly, you could do something like this:
SELECT DATEPART(year, date1) Year, DATEPART(month, date1) Month, SUM(value_col)
FROM $Table
-- WHERE CLAUSE ?
GROUP BY DATEPART(year, date1),
DATEPART(month, date1)

Effective date statement where date spans multiple columns

I'm working on a DB2 database and trying to get records by effective date. The only catch is the effective date fields are spanned across 4 columns (month, day, century, year). I think I have the date piece figured out in the select but when I add the where clause I'm having problems. (note that I'm using the digits command to pad because the year 2005 yields just 5 in the year field)
select date(concat(digits(vsmo),concat('/',concat(digits(vsdy),
concat('/',concat(digits(vsct),digits(vsyr))))))) from
ddpincgr d
where (SELECT MAX(<NOT SURE WHAT TO PUT IN HERE>) FROM ddpincgr a WHERE a.vgrno = d.vgrno) <= date('1/1/2000')
Ideas?
Turn it into a sub-query
select *
from (select date(concat(digits(vsmo),concat('/',concat(digits(vsdy),
concat('/',concat(digits(vsct),digits(vsyr))))))) as myDate from
ddpincgr d) as myTable
where max(myTable.myDate) <= date('1/1/2000')
Can't you just put the entire concatenation in the select?
select date(concat(digits(vsmo),concat('/',concat(digits(vsdy), concat('/',concat(digits(vsct),digits(vsyr)))))))
from ddpincgr d
where ( SELECT MAX(date(concat(digits(vsmo),concat('/',concat(digits(vsdy), concat('/',concat(digits(vsct),digits(vsyr))))))))
FROM ddpincgr a
WHERE a.vgrno = d.vgrno) <= date('1/1/2000')