query for succesive customer orders - mysql

How do I write a query to display the cust_id and cust_name_last for each customer who had orders in two successive months in the current year. (successive meaning they follow each other 'may, june')
for example: customer 3 has orders in May and June of this year.
select cust_id, cust_name_last
from customer
where date_sub (order_date, interval 1 month)
and date_sub (order_date, interval 2 months)

"I just want to know how to find customers with orders in consecutive months in a year"
Could you try this?
SELECT DISTINCT month1.cust_id, month1.cust_name_last
FROM customer month1 INNER JOIN customer month2
ON month1.cust_id = month2.cust_id
AND YEAR(month2.order_date) = YEAR(month1.order_date)
AND MONTH(month2.order_date) - MONTH(month1.order_date) = 1;
If you want to find consecutive orders including another years (e.g 2013-12 => 2014-01), need to check overflows something like as follows
SELECT DISTINCT month1.cust_id, month1.cust_name_last
FROM customer month1 INNER JOIN customer month2
ON month1.cust_id = month2.cust_id
AND (YEAR(month2.order_date) - YEAR(month1.order_date)) * 12 + (MONTH(month2.order_date) - MONTH(month1.order_date)) = 1;
If preceding SQL does not work for you, We are highly appreciated when you post your schema and sample data on sqlFiddle http://www.sqlfiddle.com/.

Related

MySQL Query - Duplicate Payments for 12 months

I have a database that has payments called PrePay. Customers pay 12 months in one payment.
I need to have this single payment show up as 12 payments (12 records).
Here's my query:
SELECT account, startdate, servdef
FROM PAYHIST
WHERE account = 5543
startdate is a date field
This shows the 3 payments over 3 years:
I would like to produce 11 payments for each account and servdef after the first payment. So the 06-22-2018 would have 11 records following it with the months to follow i.e.
Can you please tell me how to produce the records like this?
Join with a table that returns the number of months you want to expand each row to.
SELECT account, DATE_ADD(startdate, INTERVAL n MONTH) AS startdate, servdev
FROM PAYHIST
CROSS JOIN (
SELECT 0 AS n
UNION
SELECT 1
UNION
SELECT 2
...
UNION
SELECT 11) AS q
WHERE account = 5543
ORDER BY startdate, n

efficient way to find last week customer

I have 3 columns(customerid, date_purchased, item) table with 2 weeks of data. I want to retrieve the customers that only bought from the first week. My logic is to find the max date subtract it all the rest of the dates and retrieve customers where that difference equal or less than 7. Here is what I did, but I have a problem with my query.
select distinct(customerid) from customer where datediff(max(date_purchased),Orderdate)<=7;
You could filter with a correlated subquery:
select distinct customerid
from customer
where date_purchased > (
select max(date_purchased) - interval 7 day from customer
)
You can first group by max() date_purchased per customer id then join it to get orderdate less than 7 days from your date of purchase.
select distinct(customerid)
from customer t1
inner join
(select max(date_purchased) date_purchased, customerid as date_purchased
from customer group by customerid) t2
on t2.customerid = t1.customerid
where datediff(t2.date_purchased, t1.Orderdate) <= 7
You can do this with aggregation, if you prefer:
select customerid
from customer
group by customerid
having max(date_purchased) > max(max(datepurchased)) over () - interval 7 day;

SQL: How To Query my customers who made a purchase after 6 months of registering with us?

I have a table that I can pull up that shows daily if a customer made a purchase or not and the values are 0 or 1 for the day with the list of customers.
Table = Customers_daily,
column = made_purchase = 1 or 0
Select date_utc, count(distinct customer_id), made_purchase
from customers_daily
If i wanted to analyze the customers who made a purchase only in their 6th month since reg_date where should i specify that?
this is the output im looking for
Im just trying to make sure on this date_utc we are pulling the customers who are in their 6th month since registration date
http://sqlfiddle.com/#!9/b65b3fd/1
SELECT date_utc,
count(distinct customer_id),
MAX((date_utc >= reg_date + INTERVAL 5 MONTH) AND (date_utc <= reg_date + INTERVAL 6 MONTH))
FROM customers_daily
GROUP BY customer_id
The only thing I can't get is count(distinct customer_id) - it will always return 1, since I GROUP BY customer_id?
But if you want to GROUP BY date_utc - than what made_purchase meaning over many different customers?
Please provide sample of raw data and expected result.

Select from 2 tables only the new entries in table 2

I got 2 tables, Customers and Payment. I'm trying to select only the new customers that have payments in the specified month and year, and no previous payments in another month.
table Customer
id - name
table Payment
id - id_customer - month - year - amount
SELECT * FROM customer, payment
WHERE Customer.id = Payment.id_customer
AND month = '$month'
AND year = '$year'
That gets me all the payments in a specific month and year, but I don't know how to exclude all the customers that had other previous payments.
Thank you for your time.
I don't think that you could achieve this without a third table. What you can do is create a third table with all the ids that you have selected in query and update it every time you run a select query.
Then the below query might work:
SELECT * FROM customer c, payment p WHERE c.id = p.id_customer
AND month = '$month'AND year = '$year'AND p.id NOT IN (SELECT id FROM
third_table)
Hope it answers your question.
To get the first date of payment, use GROUP BY. But, you will have to convert the value to something like a date first:
SELECT p.id_customer, MIN(CONCAT_WS, '-', p.year, p.month)) as first_yyyymm
FROM payment p
GROUP BY p.id_customer;
You should store the payment date as a date.

need to fetch all the students who have not paid for the current month

I have two tables
Students table :
id studentname admissionno
3 test3 3
2 test2 2
1 test 1
2nd table is fee :
id studentid created
1 3 2015-06-06 22:55:34
2 2 2015-05-07 13:32:48
3 1 2015-06-07 17:47:46
I need to fetch the students who haven't paid for the current month,
I'm performing the following query:
SELECT studentname FROM students
WHERE studentname != (select students.studentname from students
JOIN submit_fee
ON (students.id=submit_fee.studentid)
WHERE MONTH(CURDATE()) = MONTH(submit_fee.created)) ;
and I'm getting error:
'#1242 - Subquery returns more than 1 row'
Can you tell me what the correct query is to fetch all the students who haven't paid for the current month?
Use not in, please try query below :
SELECT s.*
FROM students s
WHERE s.id NOT IN ( SELECT sf.studentid FROM studentfees sf WHERE month(sf.created) = EXTRACT(month FROM (NOW())) )
You want to use not exists or a left join for this:
select s.*
from students s
where not exists (select 1
from studentfees sf
where s.id = sf.studentid and
sf.created >= date_sub(curdate(), interval day(curdate) - 1) and
sf.created < date_add(date_sub(curdate(), interval day(curdate) - 1), 1 month)
)
Note the careful construction of the date arithmetic. All the functions are on curdate() rather than on created. This allows MySQL to use an index for the where clause, if one is appropriate. One error in your query is the use of MONTH() without using YEAR(). In general, the two would normally be used together, unless you really want to combine months from different years.
Also, note that paying or not paying for the current month may not really answer the question. What if a student paid for the current month but missed the previous month's payment?