Writing sql queries from multiple tables - sql

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')

Related

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.

I'm trying to use an aggregate function in order to consolidate the data but I'm not sure what I'm doing wrong

I have to find the total price per unit quantity and price. How can I make this work in a way where I can consolidate all the orders from one person with the total price that they ordered?
I'm new to SQL and not sure where to start to fix this.
SELECT DISTINCT Orders.OrderID, Customers.ContactName, Orders.OrderDate, [Order
Details].Quantity * [Order Details].UnitPrice
FROM Orders, Customers, [Order Details]
WHERE Orders.CustomerID = Customers.CustomerID
AND Orders.ShipCountry = 'Spain'
Three important things I can advice you to do:
Use explicit JOIN syntax: don't write your tables separately with comma, use explicit JOINs against them so it forces you to write their link at that moment and it's easier to read later. Your attempt was missing a link between the orders and the order details, probably making a lot of duplicates on your results.
Aggregates needs a GROUP BY. Whenever you want to apply aggregate functions like SUM, MAX, COUNT, you will (mostly) need a set of columns you want to group together. These columns go in the GROUP BY clause.
Don't use DISTINCT if you are unsure of the results you are getting. It seems that you used DISTINCT to cover up the missing link between orders and order details, so it just list uniques instead of the actual data your select is returning.
SELECT
C.CustomerID,
C.ContactName,
O.OrderID,
O.OrderDate,
TotalPrice = SUM(D.Quantity * D.UnitPrice)
FROM
Orders AS O
INNER JOIN Customers AS C ON O.CustomerID = C.CustomerID
INNER JOIN [Order Details] AS D ON O.OrderID = D.OrderID
WHERE
O.ShipCountry = 'Spain'
GROUP BY
C.CustomerID,
C.ContactName,
O.OrderID,
O.OrderDate
I think you want to do the join like this...
SELECT DISTINCT Orders.OrderID, Customers.ContactName, Orders.OrderDate,
[Order Details].Quantity * [Order Details].UnitPrice FROM Orders left join
Customers on Orders.CustomerID = Customers.CustomerID left join [Order
Details] on Orders.CustomerID = [Order Details].CustomerID where
Orders.ShipCountry = 'Spain'

Query Issues! Assistance requested

Not sure what is wrong with my query, but I can't get it to return any results. I'm using the 2012 version of Northwind as far as I know, and I am trying to get the ProductID, ProductName, Supplier Name, and Quantity purchased for each customer, whose value I am retrieving from a DropDownList as the parameter p1.
My query is as follows:
SELECT Products.ProductID,
Products.ProductName,
Suppliers.CompanyName,
[Order Details].Quantity
FROM Customers
INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Products ON [Order Details].ProductID = Products.ProductID
INNER JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID
WHERE (Orders.CustomerID = #p1);
If anyone can figure out the issue, I would greatly appreciate it.
When i run your query without the parameter the result is just fine, so we're safe to say there is something wrong with your input.
when i run it like this there is also no problem, didnt you forget something like the DECLARE?
DECLARE #p1 NVARCHAR(30)
SET #p1 = 'VINET'
Cheers!

Not understanding why I am getting this error

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.

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