This is working fine
SELECT i.*,o.*,p.*
FROM orders o
INNER JOIN oitems i
ON i.orderid = o.orderid
LEFT OUTER JOIN products p
ON i.catalogid = p.catalogid
however i want to perform a nested select as an example this is giving the coulmn x exists more than once
SELECT AA.*,
FROM (
SELECT i.*,o.*,p.*
FROM orders o
INNER JOIN oitems i
ON i.orderid = o.orderid
LEFT OUTER JOIN products p
ON i.catalogid = p.catalogid ) AA
i know the second example makes no sense , but i need another select with groupping, is there a way to fix the coulm exists more than once error without having to specify the column names in the select statement?
By using *, you are getting the same column more than once in your output. To avoid, this, specifically state the columns you want returned, instead.
The culprits are likely orderid and catalogid which both exist in more than one table, but there may be others.
You have mention column names specifically. I can see that you are using "*". you have to use like select i.columnName,o.columnName etc
Related
Can anyone who knows SQL, specifically the flavor used in Microsoft Access 2013, tell me what I'm doing wrong here?
SELECT custid, custname, ordno, itemno, itemname
FROM cust
INNER JOIN order
ON cust.custid = order.custid
INNER JOIN orderitems
ON order.ordno = orderitems.ordno
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
I've already read other, similar questions, and tried the methods they used in their solutions, but I'm getting a "Syntax error in FROM clause.", almost no matter what I try.
* * *
SOLUTION: Thanks for the replies! In addition to adding square brackets around "order" and using TableName.ColumnName syntax in SELECT, I had to use parentheses for my multiple INNER JOINs. Here is the fixed code:
SELECT cust.custid, cust.custname, [order].ordno, orderitems.itemno, inv.itemname
FROM ((cust
INNER JOIN [order]
ON cust.custid = [order].custid)
INNER JOIN orderitems
ON [order].ordno = orderitems.ordno)
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
SELECT cust.custid --<-- Use two part name here
,cust.custname
,[order].ordno
,orderitems.itemno --<-- Only guessing here use the correct table name
,inv.itemname --<-- Only guessing here use the correct table name
FROM cust
INNER JOIN [order]
ON cust.custid = [order].custid --<-- used square brackets [] around ORDER as it is
INNER JOIN orderitems -- a key word.
ON [order].ordno = orderitems.ordno
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
In your Select Statament you need to use Two Part name i.e TableName.ColumnName since these column can exist in more than one Tables in your FROM clause you need to tell sql server that columns in your select coming from which table in your from clause.
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
SELECT * FROM Products_Joined, Products
WHERE p.ProductManufacturer = 'Sony'
ORDER BY p.ProductCode
I keep getting the error The multi part identifier p.ProductManufacturer could not be bound
I tried:
Setting the Order By
Adding the PRODUCTS table to the FROM
Is there something I'm missing?
You should use:
SELECT p.*, pj.*
FROM dbo.Products p
INNER JOIN dbo.ProductsJoined pj ON ..... <== add your missing JOIN condition here
WHERE p.ProductManufacturer = 'Sony'
ORDER BY p.ProductCode
First of all: never use SELECT * in your production code.
Secondly: use the proper ANSI JOIN syntax (INNER JOIN..) to clearly show what you're joining, and on what JOIN condition (which is missing in your case - you're producing a cartesian product here.....)
Third: if you use table aliases like p. - you need to define them, too!
You have no p object. You need to alias one of your tables.
SELECT * FROM Products_Joined, Products AS p
WHERE p.ProductManufacturer = 'Sony'
ORDER BY p.ProductCode
That will fix your immediate problem, however you should have a JOIN on your tables or else you are doing a CROSS JOIN, which is usually not preferable. An example of what it would look like is below.
SELECT *
FROM Products_Joined
JOIN Products AS p
ON Products_Joined.ProductsID = p.ProductsID
--This join is a guess on what the common column is between these two tables
--Change as necessary
WHERE p.ProductManufacturer = 'Sony'
ORDER BY p.ProductCode
UPDATE BASED ON YOUR COMMENT
If you received the error even with a Products.ProductManufacturer, then you are probably missing the ProductManufacturer column in the Products table. I would check your schema and verify the column exists.
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 ...
What is the most efficient way to write a select statement similar to the below.
SELECT *
FROM Orders
WHERE Orders.Order_ID not in (Select Order_ID FROM HeldOrders)
The gist is you want the records from one table when the item is not in another table.
For starters, a link to an old article in my blog on how NOT IN predicate works in SQL Server (and in other systems too):
Counting missing rows: SQL Server
You can rewrite it as follows:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
, however, most databases will treat these queries the same.
Both these queries will use some kind of an ANTI JOIN.
This is useful for SQL Server if you want to check two or more columns, since SQL Server does not support this syntax:
SELECT *
FROM Orders o
WHERE (col1, col2) NOT IN
(
SELECT col1, col2
FROM HeldOrders ho
)
Note, however, that NOT IN may be tricky due to the way it treats NULL values.
If Held.Orders is nullable, no records are found and the subquery returns but a single NULL, the whole query will return nothing (both IN and NOT IN will evaluate to NULL in this case).
Consider these data:
Orders:
OrderID
---
1
HeldOrders:
OrderID
---
2
NULL
This query:
SELECT *
FROM Orders o
WHERE OrderID NOT IN
(
SELECT OrderID
FROM HeldOrders ho
)
will return nothing, which is probably not what you'd expect.
However, this one:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
will return the row with OrderID = 1.
Note that LEFT JOIN solutions proposed by others is far from being a most efficient solution.
This query:
SELECT *
FROM Orders o
LEFT JOIN
HeldOrders ho
ON ho.OrderID = o.OrderID
WHERE ho.OrderID IS NULL
will use a filter condition that will need to evaluate and filter out all matching rows which can be numerius
An ANTI JOIN method used by both IN and EXISTS will just need to make sure that a record does not exists once per each row in Orders, so it will eliminate all possible duplicates first:
NESTED LOOPS ANTI JOIN and MERGE ANTI JOIN will just skip the duplicates when evaluating HeldOrders.
A HASH ANTI JOIN will eliminate duplicates when building the hash table.
"Most efficient" is going to be different depending on tables sizes, indexes, and so on. In other words it's going to differ depending on the specific case you're using.
There are three ways I commonly use to accomplish what you want, depending on the situation.
1. Your example works fine if Orders.order_id is indexed, and HeldOrders is fairly small.
2. Another method is the "correlated subquery" which is a slight variation of what you have...
SELECT *
FROM Orders o
WHERE Orders.Order_ID not in (Select Order_ID
FROM HeldOrders h
where h.order_id = o.order_id)
Note the addition of the where clause. This tends to work better when HeldOrders has a large number of rows. Order_ID needs to be indexed in both tables.
3. Another method I use sometimes is left outer join...
SELECT *
FROM Orders o
left outer join HeldOrders h on h.order_id = o.order_id
where h.order_id is null
When using the left outer join, h.order_id will have a value in it matching o.order_id when there is a matching row. If there isn't a matching row, h.order_id will be NULL. By checking for the NULL values in the where clause you can filter on everything that doesn't have a match.
Each of these variations can work more or less efficiently in various scenarios.
You can use a LEFT OUTER JOIN and check for NULL on the right table.
SELECT O1.*
FROM Orders O1
LEFT OUTER JOIN HeldOrders O2
ON O1.Order_ID = O2.Order_Id
WHERE O2.Order_Id IS NULL
I'm not sure what is the most efficient, but other options are:
1. Use EXISTS
SELECT *
FROM ORDERS O
WHERE NOT EXISTS (SELECT 1
FROM HeldOrders HO
WHERE O.Order_ID = HO.OrderID)
2. Use EXCEPT
SELECT O.Order_ID
FROM ORDERS O
EXCEPT
SELECT HO.Order_ID
FROM HeldOrders
Try
SELECT *
FROM Orders
LEFT JOIN HeldOrders
ON HeldOrders.Order_ID = Orders.Order_ID
WHERE HeldOrders.Order_ID IS NULL