Ambiguous Column Name Even Though Column Name and Table are Declared? - sql

I am trying to create a query based on trying to find a value in one column of a table based on the values of another column in another table. This is the code I have written so far,
SELECT OrderDetails.OrderDetailID FROM OrderDetails
INNER JOIN OrderDetails
ON Products.ProductID = OrderDetails.ProductID
WHERE Products.SupplierID="5";
By executing the code, I want to find the OrderDetailID of the row in the OrderID Table where the SupplierID in the Products table is 5. For example,
Highlighted Products Table
The SupplierID of "Queso Cabrales" is 5 and its ProductID is 11. This corresponds to the foreign key in the table OrderDetail of 11 and therefore I want the primary key of that row to be returned. In this case 1.
Highlighted OrderDetails Table
At the moment I get an "ambiguous column name" error in the first line even though I have declared both the table and the column name. Also, how am I meant to ask SQL to fetch the data regarding other tables. I know I am mean't to use "INNER JOIN" but how do I execute so the WHERE command can be used.

You have OrderDetails twice in the FROM clause but no Products. I think you mean:
SELECT od.OrderDetailID
FROM OrderDetails od INNER JOIN
Products p
ON p.ProductID = od.ProductID
WHERE p.SupplierID = 5;
Notes:
Table aliases make the query easier to write and read (the od and p).
Don't use delimiters around numeric constants. I assume that SupplierId is a number, so I removed the double quotes.

You are using two time the same column so you must resove the amvbiguity eg: this way (using two distinct alias od1, od2)
SELECT od1.OrderDetailID FROM OrderDetails od1
INNER JOIN OrderDetails as od2
ON Products.ProductID = od2.ProductID
WHERE Products.SupplierID="5";

One problem is that INNER JOIN was designed to generate duplicate columns in the result. This problem was solved in 1992 when the SQL standard introduced 'relational' join types that don't generate duplicate attributes:
SELECT OrderDetailID
FROM OrderDetails
NATURAL JOIN Products
WHERE SupplierID = 5;

Related

How to Multiply Columns From Different Tables in SQL?

What I'm trying to do is multiply two columns from separate tables. Below is the query I tried, but I'm getting a syntax error near "*".
SELECT quantity
FROM includes
INNER JOIN product
ON includes.quantity = product.productprice;
SELECT includes quantity * productprice
AS totalprice
FROM product
Quantity is one of the columns inside of the table "include" and productprice is one of the columns inside the table "product." I used INNER JOIN to try to join these tables together and tried to multiply the two columns together under a new variable totalprice. What am I doing wrong here?
I've corrected the syntax of your query but the columns in the join are surely not the ones noted.
Please replace column_name with the names of the matching columns.
SELECT quantity * productprice AS totalPrice
FROM includes
INNER JOIN product
ON includes.column_name = product.column_name;

SQL Server need to find suppliers who supply the most different products

I have two tables I need information from, Products and Suppliers. Both these tables have a SupplierID column I am trying to use to join them together to retrieve the right info.
The output I need is SupplierID and ContactName from the Suppliers table. The correct output should contain only two suppliers, so I attempted something like this, but ran into a conversion error converting nvarchar value to a data type int. I am not supposed to count how many products they supply but aggregate functions seem like the best method to me.
SELECT TOP 2 ContactName, COUNT(Products.SupplierID) AS Supply
FROM Products
LEFT JOIN Suppliers ON Suppliers.ContactName = Products.SupplierID
GROUP BY Products.SupplierID, Suppliers.ContactName
ORDER BY Supply;
I have tried many different queries but none will work. I am confused on how to join these tables without running into errors. All the products have a unique ProductID as well. The correct output should look something like this:
7 John Smith
12 John Sample
Both these tables have a SupplierID column I am trying to use to join them together to retrieve the right info
If so, you should be joining on that column accross tables.
Also, it is a good practice to use table aliases and prefix each column with the table it belongs to.
Another remark is that if you want suppliers that sell the most different products, then you want to order by descending count (not ascending).
Finally, if you want to left join, then you should start from the suppliers and then bring in the products, not the other way around.
Consider:
select top 2
s.SupplierID,
s.ContactName,
COUNT(*) as Supply
from Suppliers s
left join Products p on p.SupplierID = s.SupplierID
group by s.SupplierID, s.ContactName
order by Supply desc;
You're currently joining on two different fields:
on Suppliers.ContactName = Products.SupplierID
Presumably this should be as follows?
on Suppliers.SupplierID = Products.SupplierID

Joining tables on foreign key

I have the following three tables:
Product
Purchase (contains ProductID as foreign key)
Sale (contain ProductID as foreign key as well)
I want to form query joining these 3 tables where my result is the product name, purchased, and sold.
Product Name - (from Products table)
Purchased - (Number of occurences in Purchase table according to ProductID)
Sold - (Number of occurences in Sale Table according to ProductID)
Can you please set me on the right track by giving me hints and I'll complete by myself?
I'm betting this will get deleted...but hopefully you see this before it does. The following is really helpful in understanding the differences in the SQL JOINS. . This answer or Kyle's answers is all you need to solve your question.
Source: INNER JOIN, LEFT/RIGHT OUTER JOIN
As far as a hint, you need to use a join of some sort (join fundamentals).
A possible answer is below:
Select p.ProductName, pu.Purchased, s.Sold
From Products p
INNER JOIN Purchase pu on p.ProductID = pu.ProductID
INNER JOIN Sale s on s.ProductID = p.ProductID

How can I take values from one table, based off the values in another?

Say I have tables
Parts
PartID (Primary Key)
Part Name
Orders
OrderID (Primary Key)
CustID (Foreign Key)
OrderDetails
OrderDetailsID (Primary Key)
PartID (Foreign Key)
Quantity
OrderID (Foreign Key)
If I wanted to get Part Name for multiple PartIDs from OrderDetails, how would I go about doing this? Would I use two DataTables? I'm confused as I cannot see an efficient way to do this. The only thing that I can think of is to create a DataTable with SQL:
SELECT * FROM OrderDetails WHERE OrderID=OrderID;
and then maybe use a For loop to take each PartID, create another DataTable to find the PartName for that and then give this to a variable. There could be up to 10 PartIDs to search through and I don't want to have variables such as PartID1 PartID2 etc.
I hope I have been able to convey my problem effectively.
Thanks
EDIT:
SQLCmd = "SELECT tblParts.PartID, tblParts.PartName, tblOrderDetails.Quantity, OrderDetails.OrderID FROM tblOrderDetails, tblParts "
SQLCmd = SQLCmd & "WHERE tblParts.PartID = OrderDetails.PartID AND OrderID=" & OrderID & ";"
I think you are looking for join. The syntax depends slightly on what kind of SQL you are using, however it will generally look something like this:
SELECT `Part Name`
FROM Parts p
INNER JOIN OrderDetails o ON p.PartID = o.PartID
WHERE o.OrderDetailsID = ...;
As far as I understand it, this will create a temporary table which consists of the fields of both tables combined. In theory it would create one record in the combined table for each possible combination of records from the two original tables. To cut this down to a reasonable number, you introduce the relation p.PartID = o.PartID, which reduces it to only those combinations which are about the same PartID.
Inner join means that it will only select from orders which have a part ID associated and only parts which are in an order. LEFT and RIGHT join are able to do the opposites - select all parts even if they are not in an order (left) or all orders even if they have no parts (right).
W3Schools has some more on joins here: http://www.w3schools.com/sql/sql_join.asp
something like:
SELECT o.orderID, p.partname, od.quality
FROM orders o
INNER JOIN orderdetails od ON o.orderID = od.orderID
INNER JOIN parts p ON od.partID = p.partID
Personally though I would store the partname and price in the order details to have a historical reocrd of what was actually ordered. After all you wouldn't want the historical order to change if the price went up for instance.

SQL Syntax for Complex Scenario (Deals)

i have a complex query to be written but cannot figure it out
here are my tables
Sales --one row for each sale made in the system
SaleProducts --one row for each line in the invoice (similar to OrderDetails in NW)
Deals --a list of possible deals/offers that a sale may be entitled to
DealProducts --a list of quantities of products that must be purchased in order to get a deal
now im trying to make a query which will tell me for each sale which deals he may get
the relevant fields are:
Sales: SaleID (PK)
SaleProducts: SaleID (FK), ProductID (FK)
Deals: DealID (PK)
DealProducts: DealID(FK), ProductID(FK), Mandatories (int) for required qty
i believe that i should be able to use some sort of cross join or outer join, but it aint working
here is one sample (of about 30 things i tried)
SELECT DealProducts.DealID, DealProducts.ProductID, DealProducts.Mandatories,
viwSaleProductCount.SaleID, viwSaleProductCount.ProductCount
FROM DealProducts
LEFT OUTER JOIN viwSaleProductCount
ON DealProducts.ProductID = viwSaleProductCount.ProductID
GROUP BY DealProducts.DealID, DealProducts.ProductID, DealProducts.Mandatories,
viwSaleProductCount.SaleID, viwSaleProductCount.ProductCount
The problem is that it doesn't show any product deals that are not fulfilled (probably because of the ProductID join). i need that also sales that don't have the requirements show up, then I can filter out any SaleID that exists in this query where AmountBought < Mandatories etc
Thank you for your help
I'm not sure how well I follow your question (where does viwSaleProductCount fit in?) but it sounds like you will want an outer join to a subquery that returns a list of deals along with their associated products. I think it would go something like this:
Select *
From Sales s Inner Join SaleProducts sp on s.SaleID = sp.SaleID
Left Join (
Select *
From Deals d Inner Join DealProducts dp on d.DealID = dp.DealId
) as sub on sp.ProductID = sub.ProductID
You may need to add logic to ensure that deals don't appear twice, and of course replace * with the specific column names you'd need in all cases.
edit: if you don't actually need any information from the sale or deal tables, something like this could be used:
Select sp.SaleID, sp.ProductID, sp.ProductCount, dp.DealID, dp.Mandatories
From SaleProducts sp
Left Join DealProducts as dp on sp.ProductID = dp.ProductID
If you need to do grouping/aggregation on this result you will need to be careful to ensure that deals aren't counted multiple times for a given sale (Count Distinct may be appropriate, depending on your grouping). Because it is a Left Join, you don't need to worry about excluding sales that don't have a match in DealProducts.