query returns more than one row - mysql

I'm trying to get the total rental amount for each client from Sakila example database
so I tried with the following query:
select customer.customer_id, customer.first_name,
(select sum(payment.amount) from customer
inner join rental on customer.customer_id=rental.customer_id
inner join payment on rental.rental_id=payment.rental_id group by payment.amount)
from customer
inner join rental on customer.customer_id=rental.customer_id
inner join payment on rental.rental_id=payment.rental_id
group by customer.customer_id;
and I get this "Subquery returns more than one row". Do you know what could be wrong? Thank you

This is your query, with some reformatting and the use of table aliases:
select c.customer_id, c.first_name,
(select sum(p2.amount)
from customer ce inner join
rental r2
on c2.customer_id = r2.customer_id inner join
payment p2
on r2.rental_id = p2.rental_id
group by p2.amount
-------^
)
from customer c inner join
rental r
on c.customer_id = r.customer_id inner join
payment p
on r.rental_id = p.rental_id
group by c.customer_id;
I've highlighted the specific cause of your problem. But the fix is to radically simplify the query:
select c.customer_id, c.first_name, sum(p.amount)
from customer c left join
rental r
on c.customer_id = r.customer_id left join
payment p
on r.rental_id = p.rental_id
group by c.customer_id;

Is that the result you're looking for?
SELECT C.customer_id
,C.first_name
,SUM(P.amount) AS [total_amount]
FROM customer C
INNER JOIN rental R ON R.customer_id = C.customer_id
INNER JOIN payment P ON P.rental_id = R.rental_id
GROUP BY C.customer_id, C.first_name
-- Condition to get only the largest amount
-- without using an ORDER BY clause
HAVING SUM(P.amount) = (SELECT MAX(SUM(P2.amount))
FROM rental R2
INNER JOIN payment P2 ON P2.rental_id = R2.rental_id
GROUP BY R2.customer_id)
Hope this will help you.

Related

I want to return all the data in the table

I'm new to MySQL. I created a view as orders to get order data.
I want to return all the order information but it only returns the orders where the discount has been applied. My code is below.
CREATE VIEW orders
AS SELECT order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail AS o INNER JOIN delivery AS d ON d.delivery_number = o.delivery_number
INNER JOIN staff AS s ON d.staff_id = s.staff_id
INNER JOIN vehicle AS v ON s.staff_id = v.staff_id
INNER JOIN product AS p ON o.product_id = p.product_id
INNER JOIN discount AS e ON e.discount_name = o.disocunt_name;
It gets an answer like
While that answer is correct I want all the orders to return not just orders with discounts. Please Help.
Use left joins. Start with the table you want to keep all of -- orders_detail:
SELECT o.order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail o LEFT JOIN
delivery d
ON d.delivery_number = o.delivery_number LEFT JOIN
staff s
ON d.staff_id = s.staff_id LEFT JOIN
vehicle v
ON s.staff_id = v.staff_id LEFT JOIN
product p
ON o.product_id = p.product_id LEFT JOIN
discount e
ON e.discount_name = o.discount_name;
Note: You should qualify all column references.

inner-join mysql x3

I need to display cust_id, the customer forename and surname, the product name<-(from products table) and date of sale<--(from sales table), also I need to display in order of the most recent dates first.
This is what I have got so far:
SELECT
customer.cust_id,
customer.forename,
customer.surname,
products.prod_name,
sales.Date_of_sale
FROM customers c
INNER JOIN sales s ON c.cust_id = s.cust_id
INNER JOIN products p ON s.product_id = p.product_id
ORDER BY s.Date_of_sale DESC
Any help would be appreciated.
This
SELECT
c.cust_id,
c.forename,
c.surname,
p.prod_name,
s.Date_of_sale
FROM customers c
INNER JOIN sales s ON c.cust_id = s.cust_id
INNER JOIN products p ON s.product_id = p.product_id
ORDER BY s.Date_of_sale DESC
will work

Rewriting sql query without subqueries

I need some help with the followin MySQL Query
I want to rewrite my Query without any subqueries - but i dont know how..
It is a video rental store database ;)
SELECT k.first_name, k.last_name, SUM(amount) AS profit
FROM payment AS p
JOIN (SELECT c.* FROM customer AS c
JOIN rental AS r ON c.customer_id = r.customer_id
WHERE r.return_date IS NULL GROUP BY c.customer_id HAVING
COUNT(*) > '1') AS k ON p.customer_id = k.customer_id
GROUP BY k.customer_id
HAVING SUM(amount) > 100
ORDER BY profit DESC;
Thanks :)
This this:
SELECT c.first_name, c.last_name, c.customer_id,SUM(amount) AS profit
FROM payment AS p
INNER JOIN (customer c
INNER join rental r
ON c.customer_id=r.customer_id)
ON p.customer_id = c.customer_id
GROUP BY c.customer_id,c.last_name,c.first_name
HAVING SUM(amount) > 100
ORDER BY profit DESC;
using INNER JOIN will restrict this query to only those customers who have made payments.

Multiple inner joins to get a complex report, not working

For the schema below, I need to get this report
This is what I have
select c.name, sr.name, count(o.order_id)
from contact c
INNER JOIN accounts a
ON c.account_id=a.account_id
INNER JOIN sales_reps sr
ON a.sales_rep_id =sr.sales_rep_id
INNER JOIN orders o
ON a.account_id =o.account_id
where o.order_id in (
select SUM(oi.quantity*p.price) from
order_items oi INNER JOIN parts p
on oi.part_id =p.part_id
)
group by a.account_id, c.name
But this does not give any results.
Please help.
Your where condition is not right, how should be a order_id equal a sum?
Try the below:
select
c.name, sr.name, COUNT(o.order_id), SUM(op.order_total)
FROM
contact c
INNER JOIN
accounts a ON c.account_id = a.account_id
INNER JOIN
sales_reps sr ON a.sales_rep_id = sr.sales_rep_id
INNER JOIN
orders o ON a.account_id = o.account_id
INNER JOIN
(SELECT
oi.order_id, SUM(oi.quantity * p.price) AS order_total
FROM
order_items oi
INNER JOIN
parts p ON oi.part_id = p.part_id
GROUP BY
oi.order_id
) op ON o.order_id = op.order_id
WHERE o.delivery_data >= CURDATE()
GROUP by c.contact_id
It won't give results as your WHERE ... IN SELECT is based on a query returning a sum() value which will not equal a key (most likely), or incorrect at best... and since you are dealing with a quantity and price which will have decimal precision (typically), you won't even get that to match even LESS likely...
I would swap the query around to pre-qualify the orders within a given date in question and sum that... THEN join to rest...
select
c.name,
sr.name,
PreQualified.NumberOrders,
PreQualified.OrderTotal
from
( select
o.Account_ID,
count( distinct o.order_id ) as NumberOrders,
sum( oi.quantity * p.price ) as OrderTotal
from
orders o
join order_items oi
on o.order_id = oi.order_id
join parts p
on oi.part_id = p.part_id
where
o.Delivery_Date >= CURDATE()
group by
o.Account_ID ) as PreQualified
JOIN Accounts a
on PreQualified.Account_ID = a.Account_ID
Join Contact C
on a.Account_ID = c.Account_ID
JOIN Sales_Reps sr
ON a.sales_rep_id = sr.sales_rep_id
If you want to count records use
count(*)
Instead of
count(o.order_id)

Mysql Query: Find Customer W/Orders but without Payment

As the title says, i am trying to find the customer's who have made orders but have not made payments yet.
I have Three tables;
Customers, Payments, Orders
The sql i have so far gives me (nested query) all the customers without payments, the outer query then tries to join all the customers with orders and checks if those customers are not in my inner table?
SELECT customerWOpayments.customerNumber FROM
ClassicModels.Customers c
INNER JOIN ClassicModels.Orders o ON c.customerName = o.customerNumber
NOT IN
(SELECT distinct c.customerNumber
FROM ClassicModels.Customers c
LEFT OUTER JOIN ClassicModels.Payments p ON c.customerNumber = p.customerNumber
WHERE p.customerNumber IS NULL) customerWOpayments;
I am getting a mysql syntax error at line 8 but cannot figure out why?
This should return customers who have orders but no matching payment assuming all of the keys you joined on in your original example were correct (for example c.customerName = o.customerNumber seems suspicious).
SELECT c.customerNumber
FROM ClassicModels.Customers c
INNER JOIN ClassicModels.Orders o
ON c.customerNumber = o.customerNumber
LEFT OUTER JOIN ClassicModels.Payments p
ON c.customerNumber = p.customerNumber
WHERE p.customerNumber IS NULL;
Basically you missed the WHERE clause. And your question lacks information. Please provide the Schema of your tables. Thanks!
try this one:
Are you sure with this condition ON c.customerName = o.customerNumber?
SELECT customerWOpayments.customerNumber
FROM ClassicModels.Customers c INNER JOIN ClassicModels.Orders o
ON c.customerName = o.customerNumber -- Please check this out
WHERE o.customerNumber NOT IN
(SELECT distinct c.customerNumber
FROM ClassicModels.Customers c LEFT JOIN ClassicModels.Payments p
ON c.customerNumber = p.customerNumber
WHERE p.customerNumber IS NULL);
OR Without Subquery
SELECT a.*
FROM Customers a INNER JOIN Orders b ON
a.CustomerName = b.CustomerNumber -- Please check this line
LEFT JOIN Payments c ON
b.CustomerNumber = c.CustomerNumber
WHERE c.CustomerNumber IS NULL
I believe it's a typo error on a.CustomerName = b.CustomerNumber, instead a.CustomerNumber = b.CustomerNumber
I can't tell exactly if it is because you didn't provide the schema of your tables with some dummy records.
Hope this helps.
Unlike the other solutions, this solution will not produce duplicate customer numbers when customers have more than one order.
SELECT C.customerNumber
FROM ClassicModels.Customers C
WHERE
EXISTS(
-- customer has orders
SELECT *
FROM ClassicModels.Orders AS O
WHERE O.customerNumber = C.customerNumber
)
AND NOT EXISTS(
-- customer does not have payments
SELECT *
FROM ClassicModels.Payments P
WHERE P.customerNumber = C.customerNumber
)