Conditional Record Selection in MYSQL - mysql

I am trying to build a lapsed payment report which displays the data in a quarter by Quarter Basis, but evaluated based on the year.
E.g. I would like to return all the Names of people who have payed in previous years, but not this year and display the results by quarter.
I have this so far, however getting it to return the correct names continues to elude me.
SELECT
IDNo,
Year(now()) as CurrentYear,
concat(year(pdate),'-Q',quarter(pdate)) as YrQtr,
Concat(IDNo,' - ',Fname,' ',Lname) as Fullname,
sum(amt) as Amt
FROM Payments
GROUP BY fname, lname, YrQtr
Having Sum(if(year(pdate)=Year(now()),1,0)) < 1 and (Sum(if(year(pdate)=Year(now())-1 ,1,0)) >0 or Sum(if(year(pdate)=Year(now())-2 ,1,0)) >0)
Any Help, direction, of even letting me know this is impossible would be appreciated.
thanks,
Edit:
The results would show Payer 1, who has paid in 2012 or 2013 but not 2014, with a Breakdown by Quarter - year
2012-Q1 2013-Q3
$xxx $xxx
But not payer 2, who has paid in 2012 and 2014. (or any payer which has paid in 2014)

I solved the issue using the following solution and temporary tables;
DROP temporary table IF EXISTS LapsedRPT;'
Create temporary table LapsedRPT
SELECT IDno,
Concat(IDNo,' - ',Fname,' ',Lname) as Fullname
FROM Payments
GROUP BY FullName
having year(max(ddate)) < year(now());
Select
year(now()) as CurrentYear,
Year(pdate) as PYr,
quarter(pdate) as PQTR,
concat(year(pdate),'-Q',quarter(ddate)) as YrQtr,
Fullname,
sum(amt) as Amt
from LapsedRPT
Where year(pdate) > Year(now())-3
Group by FullName, pyr, yrQtr;

Related

SQL reporting active users and logins

I have a SQL Table of logins as a data source, and each row has an id, timestamp and user_id.
Similar to this:
id
timestamp
user_id
1
2022-01-01T15:17:13.000Z
234
2
2022-01-02T15:17:13.000Z
235
I want to build a report that shows an aggregate of logins by year. So something like (for all months, just using January as an example.):
Year
Active Users in January
Logins in January
2019
500
10000
2020
600
10002
Essentially, the active users would be grouping the rows of logins by user_id, and the logins would just aggregate the timestamps by month.
Is this kind of view something I build using a SQL query?
You may use aggregation here:
SELECT
YEAR(timestamp) AS Year,
COUNT(DISTINCT user_id) AS `Active Users in January`,
COUNT(*) AS `Logins in January`
FROM yourTable
WHERE
MONTH(timestamp) = 1
GROUP BY
YEAR(timestamp);
The number of active users is given by the distinct count of users for a given year, in the month of January. The number of logins is just the number of entries for a given year in January.
If you want to report for all months and all years, then use:
SELECT
DATE_FORMAT(timestamp, '%Y-%m') AS ym,
COUNT(DISTINCT user_id) AS `Active Users per month`,
COUNT(*) AS `Logins in month`
FROM yourTable
GROUP BY 1;

How can I extract customers who have transacted since a specific date? (active customers definition)

All,
My definition of an active client is anyone who has transacted since November 2019. I am unsure how i can do this. e.g.
select
customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from
cust_orders
my table above is at transaction level e.g. transaction_id = 1, 2... etc..I roll it up at customer level but i only want customers who have transacted at least once since November 2019. I don't think it is as simple as adding: 'where yearmonth > 201911'. since e.g. if I have one customer who hasn't transacted since then i don't want any of their aggregated stats above. And if i have had customers who have transacted since november 2019, i do want their transaction counts prior to this included. perhaps i could do:
select
customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from
cust_orders where customerid in (select
distinct
customerid
from cust_orders where yearmonth > 201911))
)
does this make sense?
First, you need aggregation in your first query. Second, you can use a HAVING clause to identify the active customers:
select customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from cust_orders
group by customerid
having max(yearmonth) >= 201911;
Note: I interpret "since Nov 2011" as including that month, so I changed the comparison to >=.

query to select customers who bought only in a certain year

Hi i have a table that looks like this
I need to select customers who only bought in the year of 2015 meaning that i dont need customers who bought in 2015 and also 2016 only the ones who bought only on 2015 . but sadly i cant figure this out
any help would be Aprichiated
is it possible to write it like
select customerid
from x
where year(date)="2015" and year(date)!=2016
thank you :)
You can do it by finding the customers with a purchase in 2016 first, then taking all the customers with a purchase in 2015 except those also listed in the 2016 group:
SELECT DISTINCT t1.customerid
FROM x AS t1
LEFT JOIN (
SELECT DISTINCT customerid -- select the 2016 consumerid group
FROM x
WHERE date BETWEEN '2016-01-01' AND '2016-12-31'
) AS t2
ON t1.customerid = t2.customerid
WHERE date BETWEEN '2015-01-01' AND '2015-12-31'
AND t2.customerid IS NULL -- only take rows without consumerid match in 2016
I also added DISTINCT to avoid getting duplicates (if a client purchased several times in 2015)
As mentionned by #Strawberry, year(date) cannot use indexes, so I changed it to BETWEEN

Calculate total sales without missing values while joining two tables

I have a query
I have to calculate monthly sales per branch and customer (Data coming from one table)
Data should look like below
I can write the query for Jan_2019 total sales:
I create a temp table for Feb_2019. I can use the join and combine the 2 tables, but in Feb_2019 if there are new customers added, then when joining the tables I am missing new customers, and due to this the total sales for that month are not matching.
Can any one help?
I have written the query like this below
;with a as
(
select branchid, customer, sum(totalsales) as jan_totalsales from tableA
where year = 2019 and month = 1
group by customer, branched
), feb as
(
select branchid, customer, sum(totalsales) as feb_totalsales from tableA
where year = 2019 and month = 2
group by customer, branched
)
select a.branchid, feb.branchid, a.jan_totalsales, feb.feb_totalsales
from a
left join feb on feb.branchid = a.branchid
I have to create this in a temp table and do it for march_2019
Again, I am not getting new customers as I am joining from Jan data.
Can anyone help me to make this simple?
What you are after here is a conditional aggregate. This should get you on the right path:
SELECT branchid,
customer,
SUM(CASE WHEN [Year] = 2019] AND [Month] = 1 THEN totalsales ELSE 0 END) AS JanSales,
SUM(CASE WHEN [Year] = 2019] AND [Month] = 2 THEN totalsales ELSE 0 END) AS FebSales,
....
FROM YourTable
GROUP BY branchid,
customer;
If you don't undertstand how this works, please do ask. At the end of the day, it's you who has to support the SQL, not myself or other volunteers on Stack Overflow.

Calculate new users subscription amount MySQL

I have a dataset where I need to find out New subscribers revenue.
These are subscribers that are paying either weekly or monthly depending on the subscription they are on.
The unique identifier is "customer" and the data is at timestamp level, but I want it rolled up at monthly level.
Now for each month, we need to find out revenue for only NEW subscribers.
Basically, imagine customers being on monthly/weekly subscriptions and we only want their FIRST Payments to be counted here.
Here's a sample dataset and
created customer amount
16-Feb-18 14:03:55 cus_BwcisIF1YR1UlD 33300
16-Feb-18 14:28:13 cus_BpLsCvjuubYZAe 156250
15-Feb-18 19:19:14 cus_C3vT6uVBqJC1wz 50000
14-Feb-18 23:00:24 cus_BME5vNeXAeZSN2 162375
9-Feb-18 14:27:26 cus_BpLsCvjuubYZAe 156250
....and so on...
here is the final desired output
yearmonth new_amount
Jan - 2018 100000
Feb - 2018 2000
Dec - 2017 100002
This needs to be done in MySQL interface.
Basically, you want to filter the data to the first customer. One method of doing this involves a correlated subquery.
The rest is just aggregating by year and month. So, overall the query is not that complicated, but it does consist of two distinct parts:
select year(created) as yyyy, month(created) as mm,
count(*) as num_news,
sum(amount) as amount_news
from t
where t.created = (select min(t2.created)
from t t2
where t2.customer = t.customer
)
group by yyyy, mm
We can have sql subquery for only the 1st payment of the new customer with
amount for every month and year
The query is as follows
SELECT month(created) as mm,year(created) as yyyy,
sum(amount) as new_amount
FROM t
WHERE t.created=(select min(t2.created) from t t2 where
t2.customer=t.customer)