How to find all customers who didn't place an order? - sql

I am new to stackoverflow, I recently went through an interview as graduate developer, and I was asked a question regarding SQL.
Given two table customers and orders, how to find all cusomers who didn't place an order. Can someone tell me what would be a query to achieve this?
--Forgot to mention that I was asked to use JOIN operator for this.
EDIT: I could not find answer to this question as this was technical as well as logical. Therefore, I think my question is different from the one identified as a duplicate.

SELECT c.CustomerId
,Name
FROM dbo.Customers c
LEFT JOIN dbo.Orders o ON o.CustomerId = c.CustomerId
WHERE OrderId IS NULL

This translates into a Correlated Subquery using EXISTS:
select *
from customers as c
where not exists
( select * from orders as o
where c.customer_id = o.customer_id)
No order exists for a given customer_id

Related

Why should I join two columns when I can do it in an easier way?

So think that we’ve got two tables and in one of them, we’ve got our customers and the other has our orders in it and we’ve got a customer id in both of them.
So I want to get the orders of a specific customer and in here I’ve got two ways to do it:
I can say (Select * from orders where id = ‘1’
I can say (Select * from customers join orders on id = customers.id where id = ‘1’
So I’m asking this, why should I use the second method as it’s longer to write or are there any other uses to this?
If you have the customer id, then simply do:
select o.*
from orders o
where o.customer_id = 1;
You only need to join the tables together if you want to use other information, such as:
select o.*
from orders o join
customers c
on o.customer_id = c.customer_id
where c.email = #email;

What is wrong with my join in this query?

Im practicing basic SQL with this site http://www.sqlishard.com/Exercise
Here is the question:
S5.0 - INNER JOIN
Now that we can pull data out of a single table and qualify column
names, let's take it a step further. JOIN statements allow us to
'join' the rows of several tables together using a condition to define
how they match one another. SELECT [columns] FROM FirstTable INNER
JOIN SecondTable ON FirstTable.Id = SecondTable.FirstTableId
Try using the INNER JOIN syntax to SELECT all columns from the
Customers and Orders tables where the CustomerId column in Orders
matches the Id column in Customers. Since both tables have an Id
column, you will need to qualify the Customers id in the WHERE clause
with either the table name or a table alias.
Here is my answer:
SELECT *
FROM Customers AS c
INNER JOIN Orders AS o ON c.ID = o.ID
WHERE o.CustomerID = c.ID
The site says im wrong? Could anyone explain where i'm going wrong?
EDIT: I see now I dont need the WHERE clause, but the question states..
you will need to qualify the Customers id in the WHERE clause with
either the table name or a table alias.
Hence my confusion. Thanks none the less.
Try this way:
SELECT c.ID,o.ID
FROM Customers AS c
INNER JOIN Orders AS o ON o.CustomerID = c.ID
or using where clause
SELECT *
FROM Customers AS c, Orders AS o
where o.CustomerID = c.ID
If you use JOIN.. ON, you do not need where clause

A simple nested SQL statement

I have a question in SQL that I am trying to solve. I know that the answer is very simple but I just can not get it right. I have two tables, one with customers and the other one with orders. The two tables are connected using customer_id. The question is to list all the customers that did not make any order! The question is to be run in MapInfo Professional, a GIS desktop software, so not every SQL command is applicable to that program. In other words, I will be thankful if I get more than approach to solve that problem.
Here is how I have been thinking:
SELECT customer_id
from customers
WHERE order_id not in (select order_id from order)
and customer.customer_id = order.customer_id
How about this:
SELECT * from customers
WHERE customer_id not in (select customer_id from order)
The logic is, if we don't have a customer_id in order that means that customer has never placed an order. As you have mentioned that customer_id is the common key, hence above query should fetch the desired result.
SELECT c.customer_id
FROM customers c
LEFT JOIN orders o ON (o.customer_id = c.customer_id)
WHERE o.order_id IS NULL
... The NOT EXISITS way:
SELECT * FROM customers
WHERE NOT EXISTS (
SELECT * FROM orders
WHERE orders.customer_id = customer.customer_id
)
There are some problems with your approach:
There is probably no order_id in the customers table, but in your where-statement you refer to it
The alias (or table-name) order in the where-statement (order.customer_id) is not known because there is no join statement in there
If there would be a join, you would filter out all customers without orders, exactly the opposite of what you want
Your question is difficualt to answer to me because I do not know which SQL subset MapInfo GIS understands, but lets try:
select * from customers c where not exists (select * from order o where o.customer_id=c.customer_id)

Return customers with no sales

I'm a bit of a beginner with SQL so apologies if this seems trivial/basic. I'm struggling to get my head around it...
I am trying to generate results that show all customers that are in the customer table that have never placed an order and will therefore have no entry on the invoice table.
In other words, I want to select all customers from the customer table where there is no entry for their customer number in the invoice table.
Many thanks,
Mike
SELECT *
FROM customer c
WHERE NOT EXISTS (
SELECT 1
FROM invoice i
WHERE i.customerid = c.customerid
)
I would suggest you also read Oracle's documentation on different types of table joins here.
if customer_id is the collumn that identify the customer you should do something like this...
select * from Customer
where customer_id not in (select customer_id from invoice)
If you want to return all customer rows, then you will want to use a LEFT JOIN
select *
from customer c
left join invoices i
on c.customerid = i.customerid
where i.customerid is null
See SQL Fiddle with Demo
If you need help learning JOIN syntax, then here is a great visual explanation of joins.
A LEFT JOIN will return all rows from the customer table even if there is not a matching row in the invoices table. If you wanted to return only the rows that matched in both tables, then you would use an INNER JOIN. By adding the where i.customerid is null to the query it will return only those rows with no match in invoices.

SQLITE INNERJOIN Nightmare, need a solution to this

It's nice to find such a useful site with genius members. I have been trying to find a solution for this SQLITE problem for a while now. Google didn't help me, except in finding this website. The SQL query works fine on the MSAccess version of the same database.
Here's my SQL statement - which didn't work for me.
SELECT Invoices.InvoiceNumber, Invoices.Quantity,Invoices.Code, Invoices.Price,Invoices.Discount, Invoices.InvoiceGrandTotal, Employees.EmployeeName, Customers.CustomerName, Invoices.DateOfInvoice, [price]*[Quantity] AS Total, Customers.Address, Products.Description,Products.Unit
FROM Products
INNER JOIN (
(
( Invoices INNER JOIN InvoiceDetails
ON Invoices.InvoiceNumber = InvoiceDetails.InvoiceNumber
) INNER JOIN Customers
ON Invoices.CustomerID = Customers.CustomerID
) INNER JOIN Employees
ON Invoices.UserID = Employees.EmployeeID
) ON Products.Code = InvoiceDetails.Code
WHERE (((InvoiceDetails.InvoiceNumber)='10111'));
The error message is: "Cannot compile Select-Statement: no such column: Invoices.InvoiceNumber"
That usually just means that you mis-spelled the column name ... check your Invoices table and make sure the column is InvoiceNumber and not "Invoice_Number" or something similar ...
Also, a much simpler version of this query would look something like this .. without all the strange nesting:
SELECT
Invoices.InvoiceNumber,
Invoices.Quantity,
Invoices.Code,
Invoices.Price,
Invoices.Discount,
Invoices.InvoiceGrandTotal,
Employees.EmployeeName,
Customers.CustomerName,
Invoices.DateOfInvoice,
[price]*[Quantity] AS Total,
Customers.Address,
Products.Description,
Products.Unit
FROM
Invoices
JOIN Employees
ON Employees.EmployeeID = Invoices.UserID
JOIN Customers
ON Customers.CustomerID = Invoices.CustomerID
JOIN InvoiceDetails
ON InvoiceDetails.InvoiceNumber = Invoices.InvoiceNumber
JOIN Products
ON Products.Code = InvoiceDetails.Code
WHERE
InvoiceDetails.InvoiceNumber = '10111'
I think the issue might be with case sensitivity. Unless I'm mistaken, MS Access field names are not case sensitive. Check the offending column name for the correct casing in you SQLITE table definition.