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
Related
I'm looking for a way to find all buyers who registered for the sales promotion in November 2022 only and also made at least 3 orders for the following 15 day period after the registration(OPTINDATE).
Here is my query that doesn't work:
SELECT ID, OPTINDATE,ORDERDATE, COUNT(ORDER)
FROM BUYER
INNER JOIN PURCHASE USING(ID)
WHERE OPTINDATE between '2022-11-01' and '2022-11-30'
AND ORDERDATE > OPTINDATE(day,15)
GROUP BY ID
HAVING COUNT(ORDER)>= 3;
I'Ve got syntax error.
This part doesn't make sense:
OPTINDATE(day, 15)
Perhaps you wanted to use the
ADDdate function:
ADDDATE(OPTINDATE, 15)
I have been tasked to find how many users performed a transaction in every month in 2020
I know i have two tables to work with.
Table Name: Receipts|Columns: receipt_id, collection_id, user_id, amount
Table Name: Games |Columns: game_id, collection_id, game_date_time
i tried this but I dont think it makes sense or works
select month(games.game_date_time) AS Month, sum(receipts.id) from bills
join games on bills.collection_id = games.collection_id
WHERE YEAR(games.game_date_time) = 2020
group by receipts.user_id, month(games.game_date_time)
order by month(games.game_date_time)
Use COUNT() to get a count, not SUM(). And if you want a count of users, without counting the same user twice, use COUNT(DISTINCT user_id), don't put user_id in the grouping.
SELECT MONTH(g.game_date_time) AS month, COUNT(DISTINCT r.user_id) AS users
FROM receipts AS r
JOIN games AS g ON r.collection_id = g.collection_id
WHERE YEAR(g.game_date_time) = 2020
GROUP BY month
ORDER BY month
find how many users performed a transaction in every month in 2020
SELECT COUNT(r.user_id)
FROM receipts AS r
JOIN games AS g USING (collection_id)
WHERE YEAR(g.game_date_time) = 2020
GROUP BY r.user_id
HAVING COUNT(DISTINCT MONTH(g.game_date_time)) = MONTH(CURRENT_DATE)
This query:
Selects rows for current year only.
For each user - calculates the amount of distinct months for payments for this user and compares with current month. If user has payments in each month (including current!) these values are equal.
Count the amount of users matched this condition.
PS. The query will fail in 2021 - for to receive correct info in future use
HAVING COUNT(DISTINCT MONTH(g.game_date_time)) = CASE YEAR(CURRENT_DATE)
WHEN 2020
THEN MONTH(CURRENT_DATE)
ELSE 12
END
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)
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
Hi still getting my head around MySQL so was hoping someone may be able to shed some light on this one
I have a table named customers which has the following columns
msisdn BIGINT 20
join_date DATETIME
The msisdn is a unique value to identify customers.
There is a second table named ws_billing_all which has the following structure
id INTEGER 11 (Primary Key)
msisdn BIGINT 20
event_time DATETIME
revenue INTEGER
So this table stores all transactions for each of the customers in the customers table as identified by the msisdn.
What I need to do is to determine the amount from all customers that joined on a particular day after 30 days.
So for example, on the 2nd of Dec 2010, 1,100 customers were acquired. Based on the data in ws_billing_all, how much total revenue did the customers that joined on this day generate 30 days from this date.
I will probably need another table for this but not sure and really not sure on how to go about extracting this data. Any help would be appreciated.
#Cularis was very close... You only care about those customers that joined on the ONE DAY, and want all THEIR REVENUEs earned for the next 30 days... In this scenario, a customer would never have sales prior to their join date, so I didn't add an explicit between on their actual sales dates of consideration.
SELECT
date( c.Join_Date ) DateJoined,
count( distinct c.msisdn ) DistinctMembers,
count(*) NumberOfOrders,
SUM(w.revenue) AmountOfRevenue
FROM
customers c
JOIN ws_billing_all w
ON c.msisdn = w.msisdn
AND date( w.event_time ) <= date_add( c.Join_Date, INTERVAL 30 DAY )
WHERE
c.Join_Date >= SomeDateParameterValue
group by
date( c.Join_Date )
order by
date( C.Join_Date )
EDIT -- For clarification...
If you had 150 people join on Dec 1, 45 people on Dec 2, 83 people on Dec 3, you want to see the total revenue per group of people based on the day they joined going out 30 days of their sales... So...
Joined on Number of People Total Revenue after 30 days
Dec 1 150 $21,394 (up to Dec 31)
Dec 2 45 $ 4,182 (up to Jan 1)
Dec 3 83 $ 6,829 (up to Jan 2)
Does this better clarify what you want? Then we can adjust the query...
FINAL EDIT ...
I think I have what you INTENDED (with a count of orders too that might be useful). In the future, providing a sample output of something of complex nature would be helpful, even if it was as simple as I've done here.
With respect to my WHERE clause from the customers table.... Say you only cared about customers who joined within a given time frame, or only after a given date... THIS is where you would update the clause... if you want based on ALL people, then just remove it completely.
SELECT c.msisdn, SUM(w.revenue)
FROM customers c
INNER JOIN ws_billing_all w ON c.msisdn=w.msisdn
WHERE w.event_time BETWEEN c.join_date AND DATE_ADD(c.join_date, INTERVAL 30 DAY)
GROUP BY c.msisdn
You have to join both tables on the customer id. Then select all events that happened between the join date and 30 days after that. Group by the customer id and use SUM() to get total revenue per costumer.