Dynamically reduce the number of months stored in the table - sql

I have MONTH1 and MONTH2 tables that I am using to build a query. In the final output, I need to have 12 months of retention. Currently, the MONTH2 table is empty, but the data will be added every month. My idea is to UNION the queries and set a rule that with each month, one less month of data is taken from MONTH1. As a result, the final output should have a year of data that comes partially from MONTH 1 and partially from MONTH2. Once MONTH2 has 12 months of data, the query using MONTH1 should stop adding rows.
The query is the following:
SELECT
MONTH,
COUNTRY_NAME,
WEBSITE
FROM MONTH1
GROUP BY 1,2,3
UNION ALL
SELECT
MONTH,
COUNTRY_NAME,
WEBSITE
FROM MONTH2
GROUP BY 1,2,3
What would be a good method to achieve this?

Related

I need a count of serial numbers (last 6 months) that are under warranty for a failure rate report

My table has the following columns:
SerialNo
ProductNo
WarrantyBeginDt
WarrantyEndDT
I would like to get a monthly in warranty count looking back about 6 months. I know how to get a month by specifying in the where clause. Would like to have a query that generates the last 6 months with out having to specify the month in the where clause.
SELECT count(*)
FROM Supplemental_Warranty
WHERE WarrantyBeginDt <= '6-15-2022' AND WarrantyEndDt >= '6-15-2022'
How could I create a query that looks back 6 months from the current date?
UPDATED to add group by month for 6 months to get count by month.
This should give you 6 months worth of data using system date (subtract 6 months from today) and end date/time is now so you dont have to specify specific dates, just using date add functionality to subtract 6 months from stating date.
SELECT count(*), MONTH(WarrantyBeginDt) AS CountPerMonth
FROM Supplemental_Warranty
WHERE WarrantyBeginDt BETWEEN DATEADD(MONTH, -6, GETDATE()) AND GETDATE()
--if you have any flags or other logic to identify if it is underwarranty or not
AND IsUnderWarranty = 1
GROUP BY MONTH(WarrantyBeginDt)
NOTE: Not tested but this should do it depending on your SQL technology.

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.

SQL query data that appears for consecutive years

I have tried several times to figure this out but no luck.
I have one table that I am trying to query.
InvNo (primary key),
CustID,
InvAmt,
DatePD
I want to pull all of the customers that have paid at least one invoice for 3 consecutive fiscal years. Fiscal year for this example is Aug 1 to Jul 31 of the following year. Thie InvNo is unique but the custID can appear multiple times depending on how many invoices they have paid. Can anyone help me with this?
For output I need one record per custID and how many consecutive years that CustID has paid an invoice.
CustID 333 ConsecutiveYears 7
You can get the year by either subtracting 8 months or adding four months and extracting the year. Then, lag() can solve the problem:
select distinct custid
from (select t.*, lag(yyyy, 2) over (partition by custid order by yyyy) as prev_yyyy_2
from (select distinct custid, year(dateadd(month, -8, datepd)) as yyyy
from t
) t
) t
where prev_yyyy_2 = yyyy - 2;
The innermost subquery just gets pairs of customers and year. The lag() looks two rows behind. Three years are present if "2 rows behind" is exactly 2 years ago.

Access query to pull previous month's data

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);

Determine monthly values of timestamped records

I have a SQL table with the following schema:
fruit_id INT
price FLOAT
date DATETIME
This table contains many records where the price of a given fruit is recorded at a given time. There may be multiple records in a single day, there may be
I would like to be able to fetch a list of prices for a single fruit over the last 12 months inclusive of the current month. So given a fruit_id of 2 and datetime of now(), what would the price values be for December, January, February, ... October, November?
Given the above requirements, what strategy would you use to get this data? Pure sql, fetch all prices and process in code?
Thanks for you time.
Are you talking about min price, max price, average price, or something else?
Here's a quick query to get you started, which includes min, max, and average price for each month for fruit_id 2:
select left(date,7) as the_month, min(price),max(price),avg(price)
from fruit_price
where fruit_id = 2
and date >= concat(left(date_sub(curdate(), interval 11 month),7),'-01')
group by the_month;
If I understand it correctly from -
I would like to be able to fetch a list of prices for a single fruit over the last 12 months inclusive of the current month. So given a fruit_id of 2 and datetime of now(), what would the price values be for December, January, February, ... October, November?
You want the total price for every month for a single year based on the date and fruit_if you pass in.
So,this won't give all months of an year but all months which had a price for year..in case you want all months..you would need to create a dimdate table which will have all the dates...and then join with it..
declare #passeddate=Now() --date to be calculated
declare #fruit_id=2 --fruit id to be calculated
Select
fruit_id as FruitId,
Sum(price) as MonthPrice,
Month(date) as FruitMonth
from SQL_Table
group by FruitMonth,FruitId
where fruit_id=#fruit_id and
Year(date)=Year(#passeddate)
select month(date) as "Month", distinct(price) as "Unique Price" where fruit_id = 2 group by month(date);
I'd try to state as much as possible in SQL that does not require unindexed access to data because it's usually fast(er) than processing it with the application.