Average days between first and second purchase - mysql

can someone assist with the following. I need to figure out what the average day difference is between the first and second purchase of a customer:
I have the below: can someone assist with with my query please.
SELECT src.id, AVG(DATEDIFF(dest.purchasing, src.registrations)) AS avgdays FROM
(SELECT accounts.id, accounts.`created_date` AS registrations FROM accounts
WHERE YEAR(accounts.`created_date`) =2018 AND MONTH(accounts.`created_date`) =4) src
INNER JOIN
(SELECT account_id, MIN(created_date) AS purchasing
FROM ordering
WHERE STATUS = 'Fulfilled'
GROUP BY account_id
) dest
ON
dest.account_id = src.id;

The below query will give you the average difference between 2nd purchase if customer registration date is also his first order purchase date.
select account_id,customer_created,
avg(DATEDIFF(order_created, customer_created)) from
(select a.account_id,b.created_at as order_created, a.created_at
customer_created from
(select * from accounts where YEAR(created_at) =2018 AND
MONTH(created_at) =4) a
INNER JOIN ordering b on a.account_id=b.account_id where
b.status="Delivered" ) a
where customer_created <> order_created GROUP BY a.account_id ;

Related

Total orders by new customers Each day and week

I'm fairly new to SQL and I'm trying get total orders by new customers every day and each week in Mysql ( feel free to answer in any sql versions). First I tried to get total orders by new customers every day by writing below query, however Im getting incorrect results.
select COUNT(u.orderId), date(u.createdAt) as ord_dt, u.userId
from userorder u
inner join
(
select userId, min(date(createdAt)) as first_date
from userorder
group by 1
) g
on g.userId = u.userId
where g.first_date < date(u.createdAt)
group by 3
Link to the dataset https://docs.google.com/spreadsheets/d/1fA6hAkDJgp28BF0G0aSe9Ml64S9cIwch/edit?usp=sharing&ouid=104686423957654811582&rtpof=true&sd=true
Any help is appreciated
I wrote this query to get the daily answer.
select first_order_date, sum(first_total_order) as tot from
(select user_id,min(order_date) as first_order_date,total_order as
first_total_order
from
(select userId as user_id,date(createdAt) as order_date,count(orderId)
as total_order
from userorder
group by 1,2
) as uo
group by 1) z
group by 1;

Trying to make a new table by pulling data from two tables and keep getting 'Error: Every derived table must have its own alias' on this query

I have an 'Orders' table and a 'Records' table.
Orders table has the following columns:
order_id order_date seller order_price
Records table has the following columns:
order_id record_created_at record_log
I'm trying to pull and compile the following list of data but I keep getting an error message:
order_week
seller
total_num_orders
under100_count --this is the number of orders that were < $100
over100_count --this is the number of order that >= $100
approved --this is the number of orders that were approved by the payment platform
Here's my query:
SELECT order_week, seller, total_num_orders, under100_count, over100_count, approved
FROM (
SELECT
EXTRACT(WEEK FROM order_created_at) AS order_week,
merchant_name AS seller,
COUNT(merchant_name) AS total_num_orders,
SUM(DISTINCT total_order_price < 100) AS under100_count,
SUM(DISTINCT total_order_price >= 100) AS over100_count
FROM orders o
GROUP BY order_week, seller)
INNER JOIN (
SELECT
COUNT(DISTINCT o.order_id) AS approved
FROM records r
WHERE record_log = 'order approved'
GROUP BY order_id)
ON l.order_id = o.order_id;
What am I doing wrong?
The subquery in the join needs an alias. It also needs to return the order_id column, so it can be joined.
inner join ( select order_id, ... from records ... group by order_id) r --> here
on l.order_id = o.order_id
I would actually write your query as:
select
extract(week from o.order_created_at) as order_week,
o.merchant_name as seller,
count(*) as total_num_orders,
sum(o.total_order_price < 100) as under100_count,
sum(o.total_order_price >= 100) as over100_count,
sum(r.approved) approved
from orders o
inner join (
select order_id, count(*) approved
from records r
where record_log = 'order approved'
group by order_id
) r on r.order_id = o.order_id;
group by order_week, seller, approved
Rationale:
you don't want, and need, distinct in the aggregate functions here; it is inefficient, and might even yield wrong results
count(*) is more efficient count(<expression>) - so, use it, unless you know why you are doing otherwise
I removed an unecessary level of nesting
If there are orders without records, you might want a left join instead.

MYSQL getting total of summed column

have this problem for a school example problem where I have to get the total salary for coaches and participants in March (done below) and then I have to sum to get the total salary due in March for all employees which I just want to add onto the end of the Total Salary column.
This is what I have so far:
(SELECT Coach.name AS Name, COUNT(*) AS 'Shows Attended In March',
dailySalary AS 'Daily Salary', sum(dailySalary) AS 'Total Salary'
FROM Coach, TVShow, CoachInShow
WHERE monthname(dateOfShow)='March' AND
Coach.idCoach=CoachInShow.idCoach AND TVShow.idShow =
CoachInShow.idShow
GROUP BY Coach.name, Coach.dailySalary)
UNION
(SELECT Participant.name AS Name, COUNT(*) AS 'Shows Attended In
March', dailySalary AS 'Daily Salary', sum(dailySalary) AS 'Total
Salary'
FROM Participant, TVShow, Contender, ContenderInShow
WHERE monthname(dateOfShow)='March' AND Participant.idContender =
Contender.idContender AND Contender.idContender =
ContenderInShow.idContender AND ContenderInShow.idShow = TVShow.idShow
GROUP BY Participant.name, Participant.dailySalary);
I tried using GROUP BY WITH ROLLBACK on the whole thing but it doesn't add up only the TotalSalary columns. I've spent a while on this and kinda stumped.
I pasted the data here for what I'm working with: https://www.db-fiddle.com/f/gPKVQrZCMkvHUqViAUzCqZ/0 http://sqlfiddle.com/#!9/535f6d/1
Put the UNION into a subquery. In the main query, sum all the counts and total salaries, and use WITH ROLLUP to get the grand total.
You don't need dailySalary in the GROUP BY clause, since it's functionally dependent on the ID.
SELECT name AS Name, SUM(count) AS `Shows Attended in March`, SUM(totalSalary) AS `Total Salary`
FROM (
SELECT Coach.name, COUNT(*) AS count, SUM(dailySalary) AS totalSalary
FROM Coach
JOIN CoachInShow ON Coach.idCoach=CoachInShow.idCoach
JOIN TVShow ON TVShow.idShow = CoachInShow.idShow
WHERE monthname(dateOfShow)='March'
GROUP BY Coach.idCoach
UNION
SELECT Participant.name, COUNT(*) AS count, SUM(dailySalary) AS totalSalary
FROM Participant
JOIN Contender ON Participant.idContender = Contender.idContender
JOIN ContenderInShow ON Contender.idContender = ContenderInShow.idContender
JOIN TVShow ON ContenderInShow.idShow = TVShow.idShow
WHERE monthname(dateOfShow)='March'
GROUP BY Participant.idParticipant
) AS x
GROUP BY Name
WITH ROLLUP
DEMO

Using a function in a where-clause

I have a MySQL-Database where I run certain Stored Procedures.
In one of them, I want to sum up the amount a certain user has to pay, the amount he already payed and return all the users, where the amount to be payed isn't equal the amount paid. I came up with the following (simplyfied) query:
SELECT userId, SUM(costs) as sum_costs,
(SELECT SUM(payed)
FROM payments p WHERE ta.userId=p.userId) as sum_payed
FROM ta
GROUP BY ta.userId
ORDER BY ta.userId;
This gives me the sum of the costs and the payment for each user. But I do not know, how I can select only the users, where costs and payment are not equal.
WHERE sum_costs != sum_payed
doesn't work, because mysql doesn't know the column 'sum_costs' in the WHERE-clause.
Any idea, how to get the selection to work?
SELECT * FROM
(
SELECT userId, SUM(costs) as sum_costs,
(SELECT SUM(payed)
FROM payments p WHERE ta.userId=p.userId) as sum_payed
FROM ta
GROUP BY ta.userId
)a
WHERE a.sum_costs <> a.sum_payed
--ORDER BY a.userId;
Update: actually no need for ORDER BY UserId since it will be ordered implicitly by GROUP BY
SELECT * from
(select userId, SUM(costs) as sum_costs
FROM ta
GROUP BY ta.userId) t1
left join
(SELECT userId,SUM(payed) as sum_payed FROM payments p group by userId) t2
on t1.UserId=t2.UserId
where t1.sum_costs<>t2.sum_payed
ORDER BY t1.userId;
WHERE SUM(costs) <> (SELECT SUM(payed) FROM payments p WHERE ta.userId=p.userId)

Need help get following query

I have three tables customer, customer_account, account_transaction
Table structure is as follow -
Customer
Id,
Branch,
Name
..
customer_account
Id,
Cust_id,
Loanamout,
EMI
account_transaction
ID,
account_id,
amount,
date
I need to get branch wise details in form of count of Loan given, sum of loan given, and sum of emi received for a particular branch. below is my current query -
SELECT
count(s.id) as cntloan,
SUM(s.Loanamout)
(
SELECT SUM(amount)
FROM account_transaction i
WHERE s.id = i.account_id
) AS curbal
From
customer as c,
customer_account as s
where c.branch = 1 and s.cust_id = c.id
It is giving me desired result for count of loan and sum of loan given. but not giving the right sum of EMI paid by customers
Can anyone help me on this.
Thanks you very much
This SQL has aggregative functions such as count and sum, so without a group by, this would not work.
SELECT customer.id,
COUNT(customer_account.id) as cntloadn,
SUM(customer_account.loan) as loan,
SUM(account_transaction.amount)
FROM customer
JOIN customer_account ON customer_account.cust_id = customer.id
JOIN account_transaction ON account_transaction.account_id = customer_account.id
GROUP BY customer.id