Not understanding why I am getting this error - sql

This is the code I did
SELECT TOP 5 ContactName FROM Customers
INNER JOIN [Order Details]ON OrderId =
CustomerID
INNER JOIN Orders ON ProductID = OrderID
WHERE UnitPrice >= 25000
ORDER BY ContactName ASC
But this is the error I am getting
Msg 209, Level 16, State 1, Line 5
Ambiguous column name 'orderID'
Can someone explain to me why I am getting this error.
This is what I am trying to do is show the most recent five orders that were purchased from a customer who has spent more than $25,000
So i am assuming to use order,product,and customer.

The column OrderID exists in both tables.

There is probably an OrderID column in both your Order Details and your Orders table, and SQL Server doesn't know which one to take.
Solution: specify which one you want to use by putting the table name in front of it:
Orders.OrderID instead of just OrderID
So your query would look like this then:
SELECT TOP 5 ContactName FROM Customers
INNER JOIN [Order Details]ON Orders.OrderId =
CustomerID
INNER JOIN Orders ON ProductID = Orders.OrderID
WHERE UnitPrice >= 25000
ORDER BY ContactName ASC

Almost certainly you have the field orderID in both the Details and the Orders table.
Clarify it with either Orders.orderID or Details.orderID.

There are 2 OrderID columns across the tables.
You can remove the ambiguity with aliases (like this) or use Orders.OrderID
SELECT TOP 5 C.ContactName
FROM
Customers C
INNER JOIN
[Order Details] OD ON C.OrderId = OD.CustomerID
INNER JOIN
Orders O ON OD.ProductID = O.OrderID
WHERE O.UnitPrice >= 25000 -- or OD?
ORDER BY C.ContactName ASC
Note: did you mean to joion Customers and [Order Details] like using Customers.OrderId?

When you JOIN multiple tables in the same query, you need to differentiate any columns which have the same name in multiple tables. Otherwise, how would the query engine know which one you're talking about?
You can do this either by prefixing the column name with <table name>. or <table alias>..
For example:
SELECT TOP 5
C.ContactName
FROM
Customers C -- Customers is aliased as "C"
INNER JOIN [Order Details] OD ON
OD.OrderId = C.CustomerID
INNER JOIN Orders O ON
OD.ProductID = O.OrderID
WHERE
OD.UnitPrice >= 25000
ORDER BY
C.ContactName ASC
Another important question... are you sure that you're joining on the correct columns there? It looks really wrong.
Finally, if this is for a homework assignment, please make sure that you tag it as such with the "homework" tag.

In your references to OrderId, you need to figure out which table you are pulling the orderId column from. (In some cases, you can just pick either table). Let's call that table .
In your query, replace orderId with .orderId.

Related

Find customer who bought least on W3schools SQL

I'm new to SQL Server and I'm trying to do some exercises. I want to find customers who bought least on W3schools database. My solution for this case is:
Join Customers with OrderDetails via CustomerID
Select CustomerNames that have least OrderID appeared after using JOIN.
Here is my query:
SELECT COUNT(OrderID), CustomerID
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(CustomerID) ASC
HAVING COUNT(OrderID) = '1'
When I ran this query, message says "Syntax error near "Having". What happened with my query?
Please help me to figure out.
My solution for this case is:
Join Customers with OrderDetails via CustomerID
Select CustomerNames that have least OrderID appeared after using JOIN.
As #thorsten-kettner lamented:
You say in your explanation that you join and then show the customer
name. Your query does neither of the two things...
Furthermore, your question has severe grammatical errors making it hard to decipher.
I want to find customers who bought least on W3schools database.
Nonetheless,
The Try-SQL Editor at w3schools.com
To get the list of customers who have at least 1 order:
SELECT C.CustomerName FROM [Customers] AS C
JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
ORDER BY C.CustomerName
To get the list of customers who have exactly 1 order:
SELECT C.CustomerName FROM [Customers] AS C
JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
HAVING COUNT(O.OrderID) = 1
ORDER BY C.CustomerName
To get the customer who made the least number of orders:
Including the ones who made no order. Use JOIN instead of LEFT JOIN if you only want to consider the ones who made at least one order.
You can remove LIMIT 1 to get the whole list sorted by the number of orders placed.
SELECT C.CustomerName, COUNT(O.OrderID) FROM [Customers] AS C
LEFT JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
ORDER BY COUNT(O.OrderID), C.CustomerName
LIMIT 1;
Addendum
As commented by #sticky-bit ,
The ORDER BY clause has to come after the HAVING clause.
You want a TOP 1 WITH TIES query, something like this:
SELECT TOP 1 WITH TIES CustomerID
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(OrderID);
In case you are using MySQL, try the following version:
SELECT CustomerID
FROM Orders
GROUP BY CustomerID
HAVING COUNT(OrderID) = (
SELECT COUNT(OrderID)
FROM ORDERS
GROUP BY CustomerID
ORDER BY COUNT(OrderID)
LIMIT 1
);

How to find the date of the last item sold sql server

Hi Guys I am having a bit of trouble writing the most efficient and optimized query for this question:
Find the order ID and date of the last discontinued item sold.
I have my code below as well as the metadata for the tables. I am not sure if my code will produce the correct output because I have no way of testing it and I am not sure if my code will be the best way to complete this query. Any advice would help.
Select
orders.orderid,
Max(orders.orderdate)
from orders
inner join order_details on orders.orderid = order_details.orderid
inner join products on order_details.productid = products.productid
where discontinued = 1
group by orders.orderid ```
Using row_number is the easiest way:
select orderID,OrderDate from (
select o.orderID,o.OrderDate,rn = row_number() over (order by orderdate desc)
from products p
join orderDetails od on od.productID=p.productID
join orders o on o.orderID=od.orderID
where p.discontinued = 1) sub
where sub.rn = 1
your query is pretty much already what you want, the fastest way is to simply order by the required column and select top 1
select top (1) o.orderid, o.orderdate
from orders o
join order_details od on od.orderid = o.orderid
join products p on p.productid = od.productid
where p.discontinued = 1
order by o.orderdate desc
This will be more performant than using a window function to number all the rows before selecting row one.
I have a very similar arrangement of tables with the ubiquitous orders/orderitems/products arrangement including a similar deleted flag for products so it's easy to test both side by side, this query is a bit more performant than using the row_number equivalent, using a table of 13.5m orders and 6m products. Execution times for both were sub-second but this query was slightly faster.

Northwind query with join on Orders and Order Details

I have written a query like below using NorthWind.
select COUNT(o.OrderId) as Orders
from Orders o
join [Order Details] od on o.OrderID = od.OrderID
The table Orders has 830 data. However when I join Orders on Order Details query gives me the number of data inside Order Details table which is 2155.
Why is the query result not 830?
select COUNT( distinct o.OrderId) as Orders
from Orders o
join [Order Details] od on o.OrderID = od.OrderID
It's because of the join. The details create a one to many relationship repeating order ID in your results. The repeated ID is then counted each time; thus inflating the count to match record count in order details. This can be avoided by either not doing the join, or by using a distinct count of orderID as listed above.
If you need any of the details from order details, or you want to exclude from your count orders without details, then you need the join. Otherwise I'd remove it and the distinct as it's just generating overhead and adding cost to getting your results.
Additionally though, if you have orders without details then and you want them included, you need to alter your join to be a LEFT join not just an join (Inner). As the join will exclude orders w/o details. If you don't want those orders w/o details in your count then an inner join is appropriate.

How do I use SQL to select rows that have > 50 related rows in another table?

I've been trying to find out how to write this query in sql.
What I need is to find the productnames (in the products table) that have 50 or more orders (which are in the order table).
only one orderid is matched up to a productname at a time so when I try to count the orderid's it counts all of them.
I can get distinct productnames but once i add in the orderid's then it goes back to having multiple productnames.
I also need to count the number of customers (in the order table) that have ordered those products.
I need some serious help ASAP! if anyone could help me figure out how to figure this out that would be awesome!
Table: Products
`productname` in the form of a text like 'GrannySmith'
Table: Orders
`orderid` in the form of '10222'..etc
`custid` in the form of something like 'SMITH'
Assuming the orders table has a field that relates back to the products table named ProductId. The SQL would translate to:
SELECT p.ProductName, Count(*)
FROM Orders o
JOIN Products p
on o.ProductId = p.ProductId
GROUP BY p.ProductName HAVING COUNT(*) >= 50
The key is in the having component of the Group By clause. I hope this helps.
You might be missing an "Order Details" table - typically, an order has several order details, and each of the order details then maps to a product - something like the sample in Northwind:
In that case, your SQL query would be something like this: join the [Order Details] table to both the [Orders] and [Products] tables, group by the product ID and name, and count the OrderID's:
select
p.ProductID, p.ProductName, count(o.OrderID)
from
[order details] od
inner join
orders o on od.OrderID = o.OrderID
inner join
products p ON od.productID = p.ProductID
group by
p.ProductID, p.ProductName
having
count(o.OrderID) > 50

Writing sql queries from multiple tables

I could use some help writing a SQL query. I'm trying to display some data from one table but the data I need depends on a value from a different table. I'm pretty new to this so I will try to explain this the best I can:
I have an Orders table with a ShipCity and OrderId columns. I would like to get the OrderId value from Orders where ShipCity = Caracas. using those distinct OrderId values, I would like to query a different table called Order Details where [Order Details].[OrderId] = [Orders].[OrderId] (= to 'Caracas').
I hope that made sense. where I'm getting stuck is I'm sure that I will either need to create some variables or a temporary table to store these values and I don't have any experience with these things yet. I'd appreciate any help. also, these are tables in the Northwind sample database if that helps. below is a dummy sample of what I'm trying to do.
Select OrderId
FROM [Orders]
WHERE ShipCity = 'Caracas'
Select OrderId
FROM [Order Details]
WHERE OrderId = (Orders.ShipCity = 'Caracas')
here's another way of looking at it:
SELECT OrderId
FROM [Order Details]
WHERE OrderId = [Orders].ShipCity = 'Caracas'
You want to use an INNER JOIN
SELECT [Order Details].*
FROM [Order Details]
INNER JOIN [Orders] ON [Orders].OrderId = [Order Details].OrderId
WHERE [Orders].ShipCity = 'Caracas'
More information about joins can be found in the Wikipedia entry or here.
you use a JOIN clause to combine data from two or more tables. Something like this, although you should double check the syntax
select *
from [Orders] o
join [Order Details] od on o.orderid = od.orderid
where o.shipcity = 'Caracas'
You need to join the two tables:
SELECT DISTINCT o.OrderId
FROM Orders o INNER JOIN [Order Details] od ON o.OrderId = od.OrderId
WHERE o.ShipCity = 'Caracas'
...but why do you need the Order Details table in the query?
How about doing with SubQuery method?
SELECT OrderId
FROM [Order Details]
WHERE (OrderId IN SELECT OrderId FROM Orders WHERE ShipCity = 'Caracas')