Aggregation using subquery: Error 1111 occurs. How do I fix it? - mysql

Please understand that I used Google Translator because I am not proficient in English.
First of all, I get error 1111 when using mysql.
The problem is to find the name of the customer whose average book table sales is higher than the average of each customer in the customer table.
Currently, the code I have written is:
1)
select customer.name from customer, Orders
where avg(Orders.saleprice) <
(select avg(Orders.saleprice) from Orders, customer
where Orders.custid = customer.custid AND Orders.custid = 1
group by orders.custid);
select customer.name from customer, Orders, book
where avg(Orders.saleprice) <
(select avg(Orders.saleprice) from Orders, customer
where Orders.custid = customer.custid group by orders.custid);
In the case of 2), I tried to compare values at a time, but the code failed because error 1111 occurred. In the case of 1), the code was written with only one custid set to '1'.
The picture above is the average of the purchase amount of each customer in each customer table.
The picture above is the average of the sales of the book table.
This is my first time using stackoverflow recommended by a subscribed YouTuber, so I am inexperienced and English is also inexperienced, but any help would be greatly appreciated.

You can solve the problem by next way:
-- select customers with average salesprice
select
customers.*,
avg(saleprice) as avgsaleprice
from customers
join orders on customers.id = orders.customer_id
group by customers.id, customers.name
-- filter result for customers having average greater then common order average
having avgsaleprice > (
select
avg(saleprice) as avgsaleprice
from orders
);
Look the fiddle at SQLize.online

Related

Identify products that have purchased more than 1 time

I need to identify products that have purchased more than 1 time.
ERD diagram looks like this:
I wrote this query
SELECT DISTINCT good_name
FROM Goods
JOIN Payments
on Payments.good = Goods.good_id
WHERE good in (SELECT good
FROM (SELECT good
, COUNT(good) as c
FROM Payments
GROUP
BY good) as a
WHERE c > 1)
It works, but is this code great?
Grouping would work better:
SELECT good_name
FROM Goods
JOIN Payments on Payments.good = Goods.good_id
GROUP BY Goods.good_id
HAVING COUNT(Payments.good) > 1
Probably you also need an index over Payments.good column.
It is also better to create another column in the table Goods which will hold success payments count and update it after each payment.

Adding column values together to form 1 result column

I have an online sales system I am developing and I’m working on the billing payment system.
I have the order total $ amount recorded on the database table with the order itself.
Example:
SELECT total FROM Orders WHERE id = '1'
Then, I’ve got another table that includes an individual record for each financial transaction (check, cc, etc.)
Example:
SELECT payment_amount FROM Payments WHERE order_id = '1'
What I would like to do is combine these two together when doing some reporting of which orders have not been paid in full and retrieve the balance of each order. I’d like to do this with a single query if possible...
This was what I tried...
SELECT o.id as order_id, o.total, (SELECT p.payment_amount FROM Payments as p WHERE o.order_id = o.id) as amount_paid_plus FROM Orders as o
This works great if there is only 1 entry in payments...but if there are two, I get this error
Subquery returns more than 1 row
I want the payments table results to be added together into one lump sum amount and returned as one variable in the query
I also need the query to still return info even if there are no payments in the payments table. It will just display amount paid as 0.
You can just change p.payment_amount to SUM(p.payment_amount) in your subquery. Note that you have an error in the subquery, it should probably be
(SELECT SUM(p.payment_amount) FROM Payments as p WHERE p.order_id = o.id)
Note change from o.order_id to p.order_id.
Try this query :
SELECT o.id, o.total, SUM(p.payment_amount) FROM Orders o, Payments p where p.order_id = o.id

MYSQL joining tables and selecting customer with no order for particular date

I am having trouble with this mysql query. I have a customer table and an orders table, linked by a customer ID. The orders table has a date field and I am trying to list the names of customers that do not have any orders for a particular month, July 2016. I was told a NOT IN might help but I'm not sure how to go about it. I looked for similar examples but they use IS NULL. I tried this but it did not like the NOT (not a valid input at this position:
SELECT customer.cust_name
FROM customer
LEFT JOIN ordertbl ON ordertbl.cust_id = customer.cust_id
WHERE order_date like '2016-07%' not in ordertbl.order_date;
I then tried this but it returned no results:
SELECT customer.cust_name
FROM customer
LEFT JOIN ordertbl ON ordertbl.cust_id = customer.cust_id
WHERE (SELECT COUNT(order_date like '2016-07%')) IS NULL;
I also found a similar example but couldn't get it, no results:
Select customer.cust_name
From customer
where ordertbl.cust_id Not in (
Select customer.cust_id
From ordertbl
Where ordertbl.order_date like '2016-07%');
I'm sure I'm going about this all wrong. I tried a few other examples but those didn't work either. Any help is appreciated.
Assuming that in the orders table, your customer ID reference is called CUSTOMER_ID, the query is:
SELECT CUSTOMER.CUST_NAME
FROM CUSTOMER
WHERE CUST_ID IN
(SELECT ORDERTBL.CUSTOMER_ID
FROM ORDERTBL
WHERE DATE <> yourdate)

Return records when table is not empty

I am brand new to SQL and can only do the most basic of SQL queries and appreciate any help with this problem.
MySQL database contains a CUSTOMER table and a PURCHASES table. If the customer has made a purchase there will be one or more serial numbers and a purchase date in the PURCHASES table.
I would like to know how to return the customer name, serial number and date of purchase for each customer who has made a purchase between two dates.
Here is a description of the tables:
PURCHASES
customer_id
serial_number
purchase date
CUSTOMER
customer_id
customer_name
customer address
Here it is:
select c.customer_name, p.serial_number, p.purchase
from purchases p, customers c
where p.customer_id = c.customer_id and
p.purchase between '2012-08-27' and '2012-08-31'
The SQL Fiddle is here so that you can play with it: http://sqlfiddle.com/#!2/e8002/3
You need to JOIN the two tables; see MySQL documentation for the joining concept.
You need to limit the query on purchases between the two dates:
WHERE purchase BETWEEN 'date1' AND 'date2'
and this will tell you the customer ID. With this you select into the Customers table, so:
SELECT customer.customer_name,
purchases.serial_number,
purchases.purchase
FROM customer
JOIN purchases ON (customer.customer_id = purchases.purchase_id)
WHERE purchases.purchase BETWEEN '2012-01-01' AND '2012-08-01';

mysql - How to fix this query?

I am really having a headache since the other day on how to fix this mysql statement to get my desired result. I also want to inform that I am new to mysql and prorgramming.
I have 4 tables CUSTOMER, CUSTOMER_ACCT_SETTING, DEBT, and PAYMENT.
Here are the 4 tables with their record so you can relate.
CUSTOMER
CUSTOMER_ACCT_SETTING
DEBT
PAYMENT
When I run this mysql statement:
SELECT C.CUSTOMER_ID, C.NAME, C.ADDRESS, C.CONTACT_NUMBER,
SUM(((CAS.INTEREST_RATE / 100) * D.AMOUNT) + D.AMOUNT) - COALESCE(SUM(P.AMOUNT), 0) AS CURRENT_BALANCE
FROM CUSTOMER C
INNER JOIN CUSTOMER_ACCT_SETTING CAS ON (C.CUSTOMER_ID = CAS.CUSTOMER_ID)
LEFT JOIN DEBT D ON (C.CUSTOMER_ID = D.CUSTOMER_ID)
LEFT JOIN PAYMENT P ON C.CUSTOMER_ID = P.CUSTOMER_ID
GROUP BY (C.CUSTOMER_ID)
ORDER BY C.NAME
The result is below:
PS: The result is ordered by name.
My question is:
1.) Why did I get a negative result on the CURRENT_BALANCE column in the first row? I am expecting the result to be around 16374.528.
My desired result is like this:
You are projecting your payments through all your debts by doing a join with both tables at the same time. So you essentially get 5 applications of your payment on customer 4 and zero applications on all the other customers. (so NULL on P.AMOUNT yields X - NULL = NULL). To see this, remove the "GROUP BY" and the "SUM" and just return your amounts paid and debited. Then if you group/sum these results manually by customer, you'll see what's going on.
To get the results you expect, you will need to use subqueries or some other mechanism like temporary tables. Something like this:
SELECT C.CUSTOMER_ID,
(SELECT SUM(P.AMOUNT) FROM PAYMENT P
WHERE P.CUSTOMER_ID = C.CUSTOMER_ID) AS TOTAL_PAID_BY_CUSTOMER
FROM CUSTOMER C
The answer to #1 is that each row in your result set has the payment attached to it. That is, for customer #1, you're getting three instances of the 8132.