Access query to pull previous month's data - sql

I have a table in Access 2013 (Table1) that contains the following columns:
ID (pk), ReportDate, Amount
The most current data is 30-50 days old. For example, today (6/22/16) the most recent data would be the 5/1/16 row, as the 6/1/16 data won't be entered until mid-July. (All dates in the ReportDate column are the 1st of the month, i.e.: 4/1/16, 5/1/16, etc.)
I need to write a query that will do a 6-month lookback, but exclude the most current month's data.
So, for example, if I ran the query today (6/22/16), I would only get the rows that correspond to the following months:
12/1/2015
1/1/2016
2/1/2016
3/1/2016
4/1/2016
The data for 5/1/16 should be excluded, as it's the most recent month.
I can pull the previous 6 months worth of data with setting the criteria (in QBE) for ReportDate to>=DateAdd("m",-6,Date()), but I can't seem to figure out how to exclude the most recent month.

This should give you the start date of the most recent month in your table:
SELECT Max(ReportDate) AS MaxOfReportDate
FROM Table1;
If that is the month you want to exclude, use that query as a subquery which you cross join back to the table. Then you can use a WHERE clause with a BETWEEN condition whose end points are determined by DateAdd() expressions based on MaxOfReportDate:
SELECT t.ID, t.ReportDate, t.Amount
FROM
Table1 AS t,
(
SELECT Max(ReportDate) AS MaxOfReportDate
FROM Table1
) AS sub
WHERE
t.ReportDate BETWEEN DateAdd('m', -6, sub.MaxOfReportDate)
AND DateAdd('m', -1, sub.MaxOfReportDate);

Related

SQL filter by two date columns in the same month

In my dataset I have column A and column B, they have different dates, sometimes one column has a date and the other don't, sometimes both have values but different months. I want to filter by the date when they are in the January.
I want both columns to have date of January '2023-01-01'
I started with
SELECT *
FROM table
WHERE DATE_TRUNC(SAFE_CAST(column_a AS DATE), MONTH) = '2023-01-01'
OR DATE_TRUNC(column_b, MONTH) = '2023-01-01'
The problem is that in some cases the column_a has a date prior January due to the or. And both dates need to be in the some month.
How can I solve that?

Calculate the monthly average including the date where data is missing

I want to calculate the monthly average of some data using SQL query where the data resides in redshift DB.
The data is present in the following format in the table.
s_date | sales
------------+-------
2020-08-04 | 10
2020-08-05 | 20
---- | --
---- | --
The data may not be present for all the date in a month. If the data is not present for a day, it should be considered as 0.
Following query using AVG() function "group by" month as gives the average of based on the data on available date.
select trunc(date_trunc('MONTH', s_date)::timestamp) as month, avg(sales) from sales group by month;
However it does not consider the data for missing dates as 0. What should be the right query to calculate the monthly average as expected?
One more expectation is that, for the current month, the average should be calculated based on the data till today. So it should not consider entire month (like 30 or 31 days).
Regards,
Paul
Using a calendar table might be the easiest way to go here:
WITH dates AS (
SELECT date_trunc('day', t)::date AS dt
FROM generate_series('2020-01-01'::timestamp, '2020-12-31'::timestamp, '1 day'::interval) t
),
cte AS (
SELECT t.dt, COALESCE(SUM(s.sales), 0) AS sales
FROM dates t
LEFT JOIN sales s ON t.dt = s.s_date
GROUP BY t.dt
)
SELECT
LEFT(dt::text, 7) AS ym,
AVG(sales) AS avg_sales
FROM cte
GROUP BY
LEFT(dt::text, 7);
The logic here is to first generate an intermediate table in the second CTE which has one record for each data in your data set, along with the total sales for that date. Then, we aggregate by year/month, and report the average sales.

Sum of shifting range in SQL Query

I am trying to write an efficient query to get the sum of the previous 7 days worth of values from a relational DB table, and record each total against the final date in the 7 day period (e.g. the 'WeeklyTotals Table' in the example below). For example, in my WeeklyTotals query, I would like the value for February 15th to be 333, since that is the total sum of users from Feb 9th - Feb 15th, and so on:
I have a base query which gets me my previous weeks users for today's date (simplified for the sake of the example):
SELECT Date, Sum("Total Users")
FROM "UserRecords"
WHERE (dateadd(hour, -8, "UserRecords"."Date") BETWEEN
dateadd(hour, -8, sysdate) - INTERVAL '7 DAY' AND dateadd(hour, -8, sysdate);
The problem is, this only get's me the total for today's date. I need a query which will get me this information for the previous seven days.
I know I can make a view for each date (since I only need the previous seven entries) and join them all together, but that seems really inefficient (I'll have to create/update 7 views, and then do all the inner join operations). I am wondering if there's a more efficient way to achieve this.
Provided there are no gaps, you can use a running total with SUM OVER including the six previous rows. Use ROW_NUMBER to exclude the first six records, as their totals don't represent complete weeks.
select log_date, week_total
from
(
select
log_date,
sum(total_users) over (order by log_date rows 6 preceding) as week_total,
row_number() over (order by log_date) as rn
from mytable
where log_date > 0
)
where rn >= 7
order by log_date;
UPDATE: In case there are gaps, it should be
sum(total_users) over (order by log_date range interval '6' day preceding)
but I don't know whether PostgreSQL supports this already. (Moreover the ROW_NUMBER exclusion wouldn't work then and would have to be replaced by something else.)
Here's a a query that self joins to the previous 6 days and sums the value to get the weekly totals:
select u1.date, sum(u2.total_users) as weekly_users
from UserRecords u1
join UserRecords u2
on u1.date - u2.date < 7
and u1.date >= u2.date
group by u1.date
order by u1.date
You can use the SUM over Window function, with the expression using Date Part, of week.
Self joins are much slower than Window functions.

How to get last and first date of every week from predefined date table (oracle SQL)

I have Table D_date in which all dates of a year, week number,quarter number etc attributes are defined. I just want to get first and last date of every week of year 2015.
Sample D_date tabe attached.
It is simple min/max if I understand you right
SELECT calendar_year_nbr, week, min(actual_date),max(actual_date)
FROM D_date
GROUP BY calendar_year_nbr, week
I just want to get first and last date of every week of year 2015.
Since you have precomputed values already stored in the table, you could directly use MIN and MAX as aggregate functions along with GROUP BY.
For example,
SELECT MIN(actual_date) min_date,
MAX(actual_date) max_date,
calendar_week_nbr
FROM d_date
WHERE calendar_year_nbr = 2015
GROUP BY calendar_week_nbr
ORDER BY min_date;
Another way is to use ROWNUM() OVER() analytic function.

Data for specific date

My report gets data for the 1st of the current month. Let's say the 1st has still not come then how would I make the report show the data for the 1st of the previous month.
Thanks.
Simply use a select top 1 from your table, filtering by extract(day from yourDateColumn) = 1 to get only the rows with the data for the 1st day of any month, and order them in descending order by your date column (order by yourDateColumn desc), so that you always get the 1st day of the last available month in your table.
Docs for Oracle EXTRACT function