Still can't delete in SQL using JOIN - sql

I am using PostgreSQL. I saw other posts with people having trouble using join while deleting, which said to specify the table you are deleting from. I did that, and this is still not working. It says there is a "syntax error at or near 'Customers'. I am using the famous Northwind database.
DELETE Customers FROM Customers INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
WHERE Customers.CustomerID = 5;
The code doesn't really do anything useful, I just want to know why I can't delete using JOIN.

As documented in the manual you can't use JOIN like that in a DELETE statement. To join tables to the base table you need to use the USING clause:
DELETE FROM Customers
using Orders
where Customers.CustomerID=Orders.CustomerID
and Customers.CustomerID = 5;
This is equivalent to the SQL without a join:
delete from customers as c
where c.customerid = 5
and exists (select *
from orders o
where o.customerid = c.customerid);

A join in a delete will never work. If you want to ensure that the customer has an order, you could try something like this:
DELETE FROM Customers
WHERE
CustomerID = 5 AND
CustomerID IN (SELECT o.CustomerID FROM Orders o);

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;

SQL - When & How to filter with JOIN

Suppose I have two tables.. One is customers and the other is orders. Orders has a foreign key that joins to the customers table. How should I go about returning data from both tables:
Filtered on a field in the orders table and,
Filtered on a field in the customers table?
Is using WHERE to filter after the JOIN in my SELECT statement the correct way to go, or putting in an AND within the JOIN statement? And would I have to use one method for one of the above situations and the other for the other one?
For example,
SELECT customers.customer_type, orders.grant_date
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3;
or
SELECT customers.customer_type, orders.grant_date
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
AND orders.order_id = 3;
I guess I can summarize my questions as:
a. Which table should I pair with my FROM statement? Should it be the one which has the foreign key i.e. orders? Or does it depend on the situation?
b. How should I filter the data? With a WHERE or an AND with the JOIN? And how is one different from the other i.e. when should I use one over the other in my two situations?
It doesn't matter whether you do
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id
Which table you make the first table is up to you. Here I would make orders the first table, because it is orders along with their customer information you are showing in your results.
With an inner join it doesn't make a difference either, whether you put criteria in your WHERE clause or ON clause.
However, it looks strange to join customers on a condition on orders:
JOIN customers ON customers.customer_id = orders.customer_id AND orders.order_id = 3
This is not how an ON clause is supposed to work. So either:
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id
WHERE orders.order_id = 3
or
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id AND orders.order_id = 3
Many people prefer the last query over the second last, because you can easily convert the inner join into an outer join. So the general advice is: put criteria on the first table in WHERE and the criteria on other tables in ON. Make this a rule of thumb.
I my experience with SQL, when using an inner join (aka. join ), order of tables after the FROM clause has never made a difference in results. Also, it has not made any difference if I used a 'where' clause or an 'and' clause after the join. But this behavior is limited ONLY and ONLY to Inner joins. If you are using left or right joins, the order as well as Where/And clauses make a lot of difference in the results returned.
I'd like to add that if you have a lot of nulls in your keys(which should never be the case), that might affect the result set in inner joins when switching between Where and And or changing the sequence of tables after from.

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

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.

Find records that do not have related records in SQL

I have 2 tables (Orders, OrderItems) that are related based on a column OrderID. I need to find all Orders that do not have any OrderItems.
We use JOIN to find related data. To find data without any related data, we can use an anti-join.
The following joins the tables, then selects those without any order items. This tends to be more efficient that a WHERE id NOT IN (...) style query.
select *
from
Orders O
left outer join OrderItems I
on I.OrderId = O.Id
where
I.Id is null
Select * From Orders Where OrderID not in (Select Distinct OrderID From OrderItems)
try with LEFT EXCEPTION JOIN
select *
from Orders
LEFT EXCEPTION JOIN OrderItems ON ...