MySQL Query to find repeats in multiple months - mysql

I am trying to find accounts in the month of November, who have repeated in either of the prior months till August (Oct, Sept, Aug).
For example, account 1243 is in November, the search should come back with the account if it was seen in Aug, Sept or Oct, if not, it doesn't display the account. Data is just 3columns, ID, Account and Date. Below is my query:
SELECT distinct account
FROM `nash`
WHERE `date`=201211
AND account IN (SELECT account
FROM `nash` where `date`=201208
OR account IN
(SELECT account
FROM `nash` where `date`=201209)
OR account IN
(SELECT account
FROM `nash` where `date`=201210));
Also note, there are dates after November as well in the same table and should not be included in the results.
Please let me know what I can do. Thanks!

The problem is that the OR logic is including anything that shows up in 201209 or 201210. The OR has lower precedence than AND, so your logic is ending up like this:
date=201211 AND account IN (SELECT account FROM nash where date=201208), or
date=201209, or
date=201210
You can get rid of the OR logic (and make the query faster because there's just one subquery scan) by changing it to this:
SELECT distinct account
FROM `nash`
WHERE `date`=201211
AND account IN (
SELECT account
FROM `nash`
WHERE `date` IN (201208, 201209, 201210)
)

SELECT * FROM `nash` a WHERE month( date ) =10
AND EXISTS ( SELECT * FROM nash b WHERE a.account = b.account AND month( b.date ) <10)
Note that you may want to change month(date) to the full date if your data in in more than one year

Related

Trying to query for email addresses with 'Open' status within Q1 and has annual value of specific amount

I have two tables, Accounts and Opportunities. Accounts table has columns account_name, account_id, and account_email_addresses. Opportunities has opp_id, account_id, opp_stage, created_date, close_date, and mrr (mrr=monthly recurring revenue)
I am wanting to query for a list of the account email addresses in 'Open' status (opp_stage), worth more than $10,000 in ANNUAL recurring revenue (I am thinking WHERE 'mrr' * 12 >= 10,000), and then lastly is within Q1 (I am thinking WHERE close_date BETWEEN '1/1/2023' AND '3/31/2023'
Can you critique my syntax and let me know if I have done anything wrong? I am particularly unsure about the WHERE NOT (the opp stage can be anything other than Closed Won or Closed Lost) and the MRR statements.
Select account_email_address, account_id
FROM Accounts
Right Join Opportunities
ON accounts.account_id=opportunities.account_id
WHERE NOT opp_stage 'Closed Won' OR 'Closed Lost'
AND close_date BETWEEN '1/1/2023' AND '3/31/2023'
AND 'mrr' * 12 >= 10,000;
The 'not' predicate operations have parser execution precedence. In your version of the condition, what you expect to see will not work. You need to write like this:
Select account_email_address, account_id
FROM Accounts
left Join Opportunities
ON accounts.account_id=opportunities.account_id
WHERE (opp_stage NOT in ('Closed Won','Closed Lost'))
AND close_date BETWEEN '1/1/2023' AND '3/31/2023'
AND 'mrr' * 12 >= 10,000;

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

Growth for each quarter+year in SQL over my user table

I am using MYSQL and I have a User database table where my registered users are stored. I'd love to see how many users have registered on an increasing timeline for each quarter. So maybe Q1 2016 I had 1000 users total, then in Q2 2016 I had 2000 users register, in Q3 2016 4000 total users registered, etc (so I want to see the increase, not just how many registered in each quarter)
From another Stack Overflow post, I was able to create a query to see it by each day:
select u.created, count(*)
from (select distinct date(DateCreated) created from `Users`) u
join `Users` u2 on u.created >= date(u2.DateCreated)
group by u.created
and this works for each day, but I'd like to now group it by quarter and year. I tried using the QUARTER(d) function in mysql and even QUARTER(d) + YEAR(d) to concat it but I still can't get the data right (The count(*) ends up producing incredibly high values).
Would anyone be able to help me get my data grouped by quarter/year? My timestamp column is called DateCreated (it's a unix timestamp in milliseconds, so I have to divide by 1000 too)
Thanks so much
I would suggest using a correlated subquery -- this allows you to easily define each row in the result set. I think this is the logic that you want:
select dates.yyyy, dates.q,
(select count(*)
from Users u
where u.DateCreated < dates.mindc + interval 3 month
) as cnt
from (select year(DateCreated) as yyyy, quarter(DateCreated) as q
min(DateCreated) as mindc
from Users u
group by year(DateCreated), quarter(DateCreated)
) dates;

MySQL - How to list all volunteers who worked no more than once per calendar year

I have a database of volunteer worker sessions going back several years. Each entry contains, among other things, the name of a volunteer, the date of a session, and the number of hours worked that day. (Yes, volunteers are identified by name only, with no protection against matching names. I didn't set this up, unfortunately.) I want to get a list of all volunteers who appear, at most, once in each calendar year. (AKA "episodic" volunteers.) How would I write this query?
select * from USERS where id in (
select u.id from
(
select
u.id, count(*)
from
USERS u
where
YEAR(date) = YEAR(CURDATE())
group by
name
Having
Count(name) <= 1
))
I couldn't test this out, but i guess this is what you want.
This might help you:
SELECT `name`,
COUNT(`name`) AS `value_occurrence`
FROM `my_table`
WHERE YEAR(START_DATE) = YEAR(CURDATE()
GROUP BY `name`
ORDER BY `value_occurrence` DESC
LIMIT 1;
The top record will be most appeared volunteer.