SQL query data that appears for consecutive years - sql

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.

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.

SQL for in between dates for multiple years

I'm doing free courses in the Oracle devgym and I came across a question about dates that I am unfamiliar with. If I have a table of sales with dates and I want to display only dates between any two given months for every possible year within the sales table how would I go about doing that. This is what I have but I don't know how to do it for multiple years without is showing everything in between those years also. I'm trying for instance to show all sales for dates in between August and December for every year in the table. Is it possible to do without knowing all the years within the table up front?
Select *
From Sale
Where SaleDate BETWEEN '08/01/2013' and '12/31/2013'
Order by SaleDate
You can use EXTRACT(MONTH FROM date) to get the month of a date
Select *
From Sale
Where EXTRACT(MONTH FROM SaleDate) BETWEEN 8 and 12
Order by SaleDate
The best way to tackle this is to use the DAYOFYEAR() function in MYSQL which makes things very easy. It returns a value from 1 to 366 for the day of the year. This totally eliminates the year restriction ALSO maintaining the bound of a single year. If you need to search between years, you have to specify the year numbers.
Select * From Sale Where SaleDate BETWEEN DAYOFYEAR(08/01/2013) and DAYOFYEAR(12/31/2013) Order by SaleDate;

Add results to a row regarding the last 12 months rows- SQL Server

At my last meeting someone asked me if it was possible to hide people who where ill since a year from a dashboard. So I'm searching for the best way to actually KNOW who has been ill for 12 months.
I am working with a table with the number of days you've been absent for every kind of absence you could have, the number of days you should have been working that month, with a row per person, department and profession each month.
So it looks something like this :
PersonID
YEAR
MONTH
DEPARTMENT
PROFESSION
Absence1
Absence2
Absence3
WORKING DAYS OF THE MONTH...
11111
2021
07
HR
ASSISTANT
0
2
0
22
11111
2021
08
HR
ASSISTANT
0
0
0
22
==> So if I'm on a row of July 2021 I need to check the lines from June 2020 to June 2021.
My guess is that I need to add a column to this table who will say (with some kind of loop maybe) "if for the last 12 months (rows) the total number of days of absence equal the number of working days of the last 12 months then "ILL FOR A YEAR OR MORE" for each person (knowing that a person can work in more than one department or more than one profession so she'll have more than one row per month).
But I really have no idea how to actually write it in a script as I usually do very basic things. I'm using SQL SERVER and have 429 207 rows in the table. I'm thinking about doing it in the whole table and not only treating this month's rows because in the dashboard we show an historic.
Your table is heavily denormalized. If you want to represent all this information in the database, I would have expected the following tables, instead of just one:
Person
Department
Illness (list of illnesses)
IllnessAbsence (join table between Person and Illness)
Either way, you can get the information you need with something like this:
I've assumed you want the whole table, so you need a window function
We need to flip the logic on its head: exclude all rows which have no non-absence in the last 12 months
SELECT
PersonID,
YEAR,
MONTH,
DEPARTMENT,
PROFESSION,
ILLNESS1,
ILLNESS2,
ILLNESS3,
[WORKING DAYS OF THE MONTH]
FROM (
SELECT *,
NotIllLast12Months = COUNT(CASE WHEN DATEFROMPARTS(YEAR + 1, MONTH, 1) >= GETDATE()
AND ILLNESS1 + ILLNESS2 + ILLNESS3 = 0 THEN 1 END)
OVER (PARTITION BY ID)
FROM HETP_ABS
) abs
WHERE NotIllLast12Months > 0;

Bigquery: How can I aggregate the data of several columns according to a specific time range?

I am new to big query and I am trying to aggregate transaction data, revenue data, and visitor data across a series of client accounts. I need the output to be grouped by clientname and by 8 month period, so each client account has 12 months of data that are aggregated (each day of the month added together in one month entry). I can only manage to get an out of the first day of each month and not everything in between added together:
SELECT
clientname,
DATE_TRUNC(PARSE_DATE('%Y%m%d',date), MONTH) as MonthStart,
SUM (totals.visits) AS visits,
SUM (totals.transactions) AS transactions,
SUM (totals.campaigns) AS campaigns,
sum (totals.totalTransactionRevenue) AS Transactionsrevenue,
FROM `prod.mar.auto` as automotive
GROUP BY
clientname,monthstart
ORDER BY
clientname,monthstart ASC
Limit 1000
The out is only providing the value for the first of the month and not the sum between the months. Can someone help point me in the right direction?
Thanks
If you want data for the last 8 or 12 months, then use a WHERE clause:
SELECT a.clientname,
SUM(a.visits) AS visits,
SUM(a.transactions) AS transactions,
SUM(a.campaigns) AS campaigns,
SUM(a.totalTransactionRevenue) AS Transactionsrevenue,
FROM `prod.mar.auto` as a
WHERE PARSE_DATE('%Y%m%d',date >= DATE_ADD(CURRENT_DATE interval -12 months)
GROUP BY clientname
ORDER BY clientname ASC
Limit 1000;
Part of the question is somewhat unclear, so I'm doing my best with the information I have.
From my understanding of your question, it seems like there is an issue with aggregating across the entire month. It is only returning one day of the month, rather than summing across the month.
If you change
DATE_TRUNC(PARSE_DATE('%Y%m%d',date), MONTH) as MonthStart
to
EXTRACT(MONTH FROM DATE) AS MonthStart
This will return the number of the month and therefore you can aggregate across because the numbers across all the date fields will be the same for each month individually.
Here is the final query:
SELECT
clientname,
EXTRACT(MONTH FROM DATE) AS MonthStart,
SUM (totals.visits) AS visits,
SUM (totals.transactions) AS transactions,
SUM (totals.campaigns) AS campaigns,
sum (totals.totalTransactionRevenue) AS Transactionsrevenue,
FROM `prod.mar.auto` as automotive
GROUP BY
clientname, MonthStart
ORDER BY
clientname, MonthStart ASC
Limit 1000
Providing Documentation to Function:
https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions

How to count the number of occurrences per month?

I have a program and want to generate reports from it. The program is for a grocery store that does deliveries. A customer places an order and the program captures the various items that the customer wishes to purchase, e.g. Order 21 and the program lists the various items relating to that specific order.
I would like to generate a SQL query that counts the number of orders that customers place each month and want it to look like this
No of orders Month
10 Jan
20 Feb
30 March
The SQL that I had which is
SELECT COUNT(OrderID) AS "Number Of Orders", datepart(month, order_date) AS "Month"
FROM "ORDER"
Group by datepart(month, order_date);
Displays
Number of Orders Month
16 9
However this is the count of all the orders for the various months and is only displayed in month 9 (September.)
Hope this will help:
select COUNT(OrderID) as "Number Of Orders",DATENAME(mm,order_date) as "Month" from "ORDER" group by DATENAME(mm,DueDate) order by 2