Error with SQL code - mysql

Trying to execute this code with COALESCE to group data together. When executing I see this error
Msg 207, Level 16, State 1, Line 11
Invalid column name 'OrderID'.
Msg 209, Level 16, State 1, Line 1
Ambiguous column name 'CustomerID'.
SELECT CustomerID,
FirstName,
LastName,
COALESCE(OrderIDCnt,0),
COALESCE(SKUCnt,0),
COALESCE(OrderTotal,0)
FROM Customer as c
left join (SELECT o.CustomerID,
SUM(OrderTotal) AS OrderTotal,
COUNT(OrderedProductSKU) AS SKUCnt,
COUNT(OrderID) AS OrderIDCnt
FROM Orders as o
inner join Orders_ShoppingCart as osc
on osc.OrderNumber=o.OrderNumber
and osc.CustomerID=o.CustomerID
GROUP BY o.CustomerID
)ord
ON ord.CustomerID = c.CustomerID

try to use c.CustomerId or ord.CustomerId

The error means that SQL parser cannot uniquely resolve the unqialified name CustomerID. There are two candidates there:
The CustomerID field of the Customer table, and
The CustomerID field of the ord sub-query.
Although the two must match, because your join condition requires that ord.CustomerID = c.CustomerID, the query parser cannot arbitrarily pick one for you. Therefore, you need to either disambiguate this manually by specifying c or ord in front of CustomerID, or pick a different name for CustomerID in the subquery.
The first approach:
SELECT c.CustomerID, -- Add c. in front of CustomerID
FirstName,
LastName,
COALESCE(OrderIDCnt,0),
COALESCE(SKUCnt,0),
COALESCE(OrderTotal,0)
FROM Customer as c
left join (SELECT o.CustomerID,
SUM(OrderTotal) AS OrderTotal,
COUNT(OrderedProductSKU) AS SKUCnt,
COUNT(o.OrderID) AS OrderIDCnt -- Disambiguated OrderID
FROM Orders as o
inner join Orders_ShoppingCart as osc
on osc.OrderNumber=o.OrderNumber
and osc.CustomerID=o.CustomerID
GROUP BY o.CustomerID
)ord
ON ord.CustomerID = c.CustomerID
The second approach:
SELECT CustomerID,
FirstName,
LastName,
COALESCE(OrderIDCnt,0),
COALESCE(SKUCnt,0),
COALESCE(OrderTotal,0)
FROM Customer as c
left join (SELECT o.CustomerID as OrderCustomerID, -- add an alias
SUM(OrderTotal) AS OrderTotal,
COUNT(OrderedProductSKU) AS SKUCnt,
COUNT(o.OrderID) AS OrderIDCnt -- Disambiguated OrderID
FROM Orders as o
inner join Orders_ShoppingCart as osc
on osc.OrderNumber=o.OrderNumber
and osc.CustomerID=o.CustomerID
GROUP BY o.CustomerID
)ord
ON ord.OrderCustomerID = c.CustomerID -- Rename the field
Edit : Disambiguated OrderID.

You have field named customerId in tables Orders and Customer and you don't specify which you want to include in select clause.
In this case you always should type the field in format alias.field

Related

How to display data from two table according to customer id in mysql

I'm trying to display data from 2 tables where 1 is customer and 2 is searches:
select product_id,product_name,product_price,customer_name,email,date_of_birth,
country,state,city,postcode from searches, customer where searches.customer_id =
customer.customer_id and customer_id='1';
I am writing this query but facing the error:
13:06:03 select product_id,product_name from searches, customer where searches.customer_id = customer.customer_id and customer_id='1' LIMIT 0, 1000 Error Code: 1052. Column 'customer_id' in where clause is ambiguous 0.000 sec
Tryed a left join ?
SELECT s.product_id, s.product_name, s.product_price, c.email, c.date_of_birth, c.country, c.state, c.city, c.postcode FROM searches AS s
LEFT JOIN customer AS c
ON s.customer_id = c.id
WHERE c.id = 1;
If a column name is strictly the same between two tables that you join together, you will always need to specify the table name (or alias) before the column name in order to let it know which field is concerned (from which table).
This is why it tells you "Column 'customer_id' in where clause is ambiguous" because it doesn't know if it is customer_id from customer table or searches table.
Solution is :
SELECT
product_id,
product_name,
product_price,
customer_name,
email,
date_of_birth,
country,
state,
city,
postcode
FROM searches s
JOIN customer c ON s.customer_id = c.customer_id
WHERE c.customer_id='1';

Un Ordered Customer

I have two tables fist one customer and second one Orderdetails. I want list of sign ups from 4th on wards and exclude the list of customers who have bought.
SELECT *
FROM Customer
WHERE RegisteredDate BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/04/2015',101))
AND CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/07/2015',101))
AND CustomerID NOT IN(SELECT *
FROM Customer c
INNER JOIN orderdetails od ON c.CustomerId = od.CustomerID
WHERE C.RegisteredDate
BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/04/2015',101))
AND CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/07/2015',101))
AND Transactionid IS NOT NULL
)
the result is:
Msg 116, Level 16, State 1, Line 13 Only one expression can be
specified in the select list when the subquery is not introduced with
EXISTS.
Remove * (all columns) in subquery and specify select CustomerID instead of *(all columns) in subquery.
Because when using NOT IN, it is expected that the number of columns return by the subquery is only one.
As mentioned in other answer IN operator only expects one column to be returned when being used with a sub-query, you should only select the cutomerID in the sub-query but if there is a chance of it returning NULL values then use EXISTS operator something like....
SELECT *
FROM Customer c1
WHERE RegisteredDate BETWEEN CONVERT(DATETIME,'12/04/2015',101)
AND CONVERT(DATETIME,'12/07/2015',101)
AND NOT EXISTS (SELECT *
FROM Customer c
INNER JOIN orderdetails od ON c.CustomerId = od.CustomerID
WHERE C.RegisteredDate
BETWEEN CONVERT(DATETIME,'12/04/2015',101)
AND CONVERT(DATETIME,'12/07/2015',101)
AND Transactionid IS NOT NULL
AND C1.CustomerID = c.CustomerID
)
You cant use select * in a subquery, you need to specify the column which in this case is customerid.
SELECT *
FROM Customer
WHERE RegisteredDate BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/04/2015',101))
AND CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/07/2015',101))
AND CustomerID NOT IN(SELECT c.CustomerID
FROM Customer c
INNER JOIN orderdetails od ON c.CustomerId = od.CustomerID
WHERE C.RegisteredDate
BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/04/2015',101))
AND CONVERT(DATETIME,CONVERT(VARCHAR(50),'12/07/2015',101))
AND Transactionid IS NOT NULL
)

SQL - How do I list rows from one table on the basis of them not appearing in another?

I have a customers table (which contains customer ID and family name) and an orders table, and have to list the ID and names of customers that didn't place an order i.e do not appear in the orders table. I tried this:
SELECT custID,familyname
FROM customers
WHERE custID =
(SELECT custID
FROM orders
WHERE COUNT(custID)<1);
but am getting an error. Do I have to use NOT EXIST? Or NOT IN?
You don't have to use not exists. You should want to:
SELECT c.custID, c.familyname
FROM customers
WHERE not exists (select 1 from orders o where o.custId = c.custId);
You can also use an outer join and filter in on those instances where there is no match:
select c.custid, c.familyname
from customers c
left join orders o
on c.custid = o.custid
where o.custid is null

SQL Query, What am I doing wrong?

Hi there fellas I'm trying to do this query but I am having trouble with it. Could anyone give me a hand I'll list below what I've done.
How busy each optometrist has been. Your SQL statement should return the full names of all optometrists, and the total number of appointments they have conducted. You must use the word ‘Optometrist’ not the positionID to select optometrists in your statement. Note that even optometrists with zero appointments should be displayed in the results.
What I've done..
SELECT firstName, lastName, optometristID, COUNT(optometristID)
FROM employee
LEFT JOIN appointment ON employee.employeeID=appointment.optometristID
GROUP BY (optometristID)
The full name, email and primary phone number and total number of invoices for all customers in ascending order of last name. Note that even customers with zero invoices should be displayed in the results.
What I've wrote..
SELECT c.firstName, c.lastName, c.primaryPhone,
(SELECT count(*) from invoice where customerID = c.customerID) as numInvoices
FROM customer c, invoice i
WHERE c.customerID = c.customerID
ORDER BY lastname ASC
Thank you!
The first one is ok for me
The second should be either
SELECT c.firstName, c.lastName, c.primaryPhone,
(SELECT count(*) from invoice where customerID = c.customerID) as numInvoices
FROM customer c
ORDER BY lastname ASC
OR
SELECT c.firstName, c.lastName, c.primaryPhone,
count(i.customerID ) as numInvoices
FROM customer c left join invoice i
on i.customerID = c.customerID
group by c.customerID
ORDER BY lastname ASC
The last one should be faster
In second query you have to write
WHERE c.customerID = i.customerID
Instead of
WHERE c.customerID = c.customerID

Error 1111 (HY000) - Invalid use of group function

I'm getting a problem when trying to run this query:
Select
c.cname as custName,
count(distinct o.orderID) as No_of_orders,
avg(count(distinct o.orderID)) as avg_order_amt
From Customer c
Inner Join Order_ o
On o.customerID = c.customerID
Group by cname;
This is an error message: #1111 (HY000) - Invalid use of group function
I just want to select each customer, find how many orders each customer has, and average the total number of orders for each customer. I think it might have a problem with too many aggregates in query.
The issue is that you need to have two separate groupings if you want to calculate the average over a count, so this expression isn't valid:
avg(count(distinct o.orderID))
Now it's hard to understand what exactly you mean, but it sounds as if you just want to use avg(o.amount) instead.
[edit] I see your addition now, so while the error is still the same, the solution will be slightly more complex. The last value you need, the avarage number of orders per customer, is not a value to calculate per customer. You'd need analytical functions to that, but that might be quite tricky in MySQL. I'd recommend to write a separate query for that, otherwise you would have very complex query which would return the same number for each row anyway.
select c.cname, o.customerID, count(*), avg(order_total)
from order o join customer using(customerID)
group by 1,2
This will calculate the number of orders and average order total (substitute the real column name for order_total) for each customer.
how many orders each customer has,
average the total number of orders.
SELECT
c1.cname AS custName,
c1.No_of_orders,
c2.avg_order_amt
FROM (
SELECT
c.id,
c.cname,
COUNT(DISTINCT o.orderID) AS No_of_orders
FROM
Customer c
JOIN Order_ o ON o.customerID = c.customerID
GROUP BY c.id, c.cname
) c1
CROSS JOIN (SELECT AVG(No_of_orders) AS avg_order_amt FROM (
SELECT
c.id,
COUNT(DISTINCT o.orderID) AS No_of_orders
FROM
Customer c
JOIN Order_ o ON o.customerID = c.customerID
GROUP BY c.id
)) c2