I need to get data from multiple tables and put it into a subform.
The SubForm columns are 'product name' and 'quantity' and they need to list out the products relating to the order ID.
The tables in question are:
PRODUCTS(productID,productName)
ORDER(orderID,prodID,quantity)
Where the prodID in ORDER refers to the PRODUCTS table.
As you can see, the problem is that the name of the product is in a different table to the order. So, the data I need to get is:
Products(productName)
Order(quantity)
In relation to the orderID.
How can I use a SQL query to get this data? I am aware of joins and so on, but I just can't see how to apply it.
Thank you. I hope this makes sense.
This is a simple inner join between the two tables to return the rows you want:
SELECT P.PRODUCTNAME, O.QUANTITY
FROM PRODUCTS P INNER JOIN ORDER O ON P.PRODUCTID = O.PRODID
WHERE O.ORDERID = <order id>
SELECT
PRODUCTS.productName AS productName,
`ORDER`.quantity AS quantity
FROM
`ORDER`
INNER JOIN PRODUCTS on `ORDER`.prodID=PRODUCTS.productID
WHERE
..
You migh also want to rename the table ORDER - using reserved words as table names is not the best of styles.
Select p.productname, q.quantity from product_table p, quantity_table q where p.productId = q.productId;
Related
I am struggling with a sql statement. I am hoping a guru can help a beginner out, currently I have multiple select in statements.. but think there is a better way as I have been stuck.
Below are the tables and pertinent columns in each table
country
-country_id
barcodes_banned_in_country
-barcode(varchar)
-country_id
-country_name
orders
-order_id
-country_name
item
-order_id
-item_id
-barcode(varchar)
The goal is to get all orders that are banned based off the barcode banned list.
Any help with this sql statement would be appreciated.
One option uses exists:
select o.*
from orders o
where exists (
select 1
from barcodes_banned_in_country bic
inner join item i on i.barcode = bic.barcode
where i.order_id = o.order_id and bic.country_name = o.country_name
)
This brings all orders whose at least one item have a barcode that is banned in the order's country.
If, on the other hand, you want the list of the banned barcodes per order, then you can join and aggregate:
select o.order_id, o.country_name, listagg(i.barcode, ',') banned_barcodes
from orders o
inner join item i
on i.order_id = o.order_id
inner join barcodes_banned_in_country bic
on i.barcode = bic.barcode
and bic.country_name = o.country_name
group by o.order_id, o.country_name
Note that, as commented by MT0, you should really be storing the id of the country in orders rather than the country name. Accordingly, you wouldn't need the country name in the banned barcodes table.
I have a table of orders, and a table of products contained in these orders. (The products-table has order_id, a foreign key referring to orders.id).
I would like to query the number of products contained in each order. However, I also want orders to be contained in the results if they do not contain any products at all.
This means that a simple
SELECT *, COUNT(*) n_products FROM `orders` INNER JOIN `products` on `products.order_id` = `orders.id` GROUP_BY `order_id`
does not work, since orders without any products disappear.
Using a LEFT OUTER JOIN instead would add rows without product-information, but the distinction between an order with 1 product and an order with 0 products is lost.
What am I missing here?
You need a left join here, and you should be counting some column from the products table:
SELECT
o.*,
COUNT(p.order_id) AS n_products
FROM orders o
LEFT JOIN products p
ON p.order_id = o.id
GROUP BY
o.id;
Note that I assume that Postgres would allow grouping by orders.id and then selecting all columns from that table. If not, then you would only be able to select o.id in addition to the count.
I have an e-commerce website (using VirtueMart) and I sell products that consist child products. When a product is a parent, it doesn't have ParentID, while it's children refer to it. I know, not the best logic but I didn't create it.
My SQL is very basic and I believe I ask for something quite easy to achieve
Select products that have children.
Sort results by prices (ASC/DSC).
SELECT * FROM Products INNER JOIN Prices ON Products.ProductID = Prices.ProductID ORDER BY Products.Price [ASC/DSC]
Explanation:
SELECT - Select (Get/Retrieve)
* - ALL
FROM Products - Get them from a DB Table named "Products".
INNER JOIN Prices - Selects all rows from both tables as long as there is a match between the columns in both tables. Rather, JOIN DB Table "Products" with DB Table "Prices".
ON - Like WHERE, this defines which rows will be checked for matches.
Products.ProductID = Prices.ProductID - Your match criteria. Get the rows where "ProductID" exists in both DB Tables "Products" and "Prices".
ORDER BY Products.Price [ASC/DSC] - Sorting. Use ASC for Ascending, DSC for Descending.
This table design is subpar for a number of reasons. First, it appears that the value 0 is being used to indicate lack of a parent (as there's no 0 ID for products). Typically this will be a NULL value instead.
If it were a NULL value, the SQL statement to get everything without a parent would be as simple as this:
SELECT * FROM Products WHERE ParentID IS NULL
However, we can't do that. If we make the assumption that 0 = no parent, we can do this:
SELECT * FROM Products WHERE ParentID = 0
However, that's a dangerous assumption to make. Thus, the correct way to do this (given your schema above), would be to compare the two tables and ensure that the parentID exists as a ProductID:
SELECT a.*
FROM Products AS a
WHERE EXISTS (SELECT * FROM Products AS b WHERE a.ID = b.ParentID)
Next, to get the pricing, we have to join those two tables together on a common ID. As the Prices table seems to reference a ProductID, we can use that like so:
SELECT p.ProductID, p.ProductName, pr.Price
FROM Products AS p INNER JOIN Prices AS pr ON p.ProductID = pr.ProductID
WHERE EXISTS (SELECT * FROM Products AS b WHERE p.ID = b.ParentID)
ORDER BY pr.Price
That might be sufficient per the data you've shown, but usually that type of table structure indicates that it's possible to have more than one price associated with a product (we're unable to tell whether this is true based on the quick snapshot).
That should get you close... if you need something more, we'll need more detail.
use the below script if you are using ssms.
SELECT pd.ProductId,ProductName,Price
FROM product pd
LEFT JOIN price pr ON pd.ProductId=pr.ProductID
WHERE EXISTS (SELECT 1 FROM product pd1 WHERE pd.productID=pd1.ParentID)
ORDER BY pr.Price ASC
Note :neither of your parent product have price in price table. If you want the sum of price of their child product use the below script.
SELECT pd.ProductId,pd.ProductName,SUM(ISNULL(pr.Price,0)) SUM_ChildPrice
FROM product pd
LEFT JOIN product pd1 ON pd.productID=pd1.ParentID
LEFT JOIN price pr ON pd1.ProductId=pr.ProductID
GROUP BY pd.ProductId,pd.ProductName
ORDER BY pr.Price ASC
You will have to use self-join:
For example:
SELECT * FROM products parent
JOIN products children ON parent.id = children.parent_id
JOIN prices ON prices.product_id = children.id
ORDER BY prices.price
Because we are using JOIN it will filter out all entries that don't have any children.
I haven't tested it, I hope it would work.
First of all, I'm practicing with Northwind database (Microsoft creation).
The table design I'm working with is:
The question I'm trying to solve is:
Which Product is the most popular? (number of items)
Well, my query was:
SELECT DISTINCT
P.ProductName
FROM
Products P,
[Order Details] OD,
Orders O,
Customers C
WHERE
C.CustomerID = O.CustomerID
and O.OrderID = OD.OrderID
and OD.ProductID = P.ProductID
and P.UnitsInStock = (SELECT MAX(P.UnitsInStock) Items
FROM Products P)
Now, I had exactly one result as they asked:
ProductName
1 Rhönbräu Klosterbier
Yet, I doublt that my query was good. Do I really need a SELECT within a SELECT?
It feels like duplication for some reason.
Any help would be appreciated. Thanks.
To get the most popular product (bestselling product) use query
SELECT ProductName, MAX(SumQuantity)
FROM (
SELECT P.ProductName ProductName,
SUM(OD.Quantity) SumQuantity
FROM [Order Details] OD
LEFT JOIN Product P ON
P.ProductId = OD.ProductID
GROUP BY OD.ProductID
) Res;
Does the most units in stock necessarily equate to the most popular product? I don't think that is always a true statement (It could even be the opposite in fact.).
To me the question is asking, which is the most popular product sold. If you think about it that way, you'd be looking at the amount sold for each product and selecting the product with the most sold.
Does that make sense?
With regards to your specific query, the query only utilizes the Products table. You make joins, but they are not used at all in the query and should get overlooked by the query optimizer.
I would personally rewrite your query as the following:
SELECT
P.ProductName
FROM
Products P
INNER JOIN
(SELECT
MAX(P.UnitsInStock) AS Items
FROM Products P) maxProd
ON P.UnitsInStock= maxProd.Items
About your question, it is perfectly acceptable to utilize a subquery (the select in the where clause). It is even necessary at times. Most of the time I would use an Inner Join like I did above, but if the dataset is small enough, it shouldn't make much difference with query time.
In this scenario, you should rethink the question that is being asked and think about what being the most popular item means.
Rethinking the problem:
Let's look at the datasets that you've shown above. Which could be used to tell you how many products have been sold? A customer would have to order a product, right? Looking at the two tables that are potentially applicable, one contains details about number of items sold, quantity, or you could think of popularity in terms of the number of times appearing in orders. Start with that dataset and use a similar methodology to what you've done, but perhaps you'll have to use a sum and group by. Why? Perhaps more than one customer bought the item.
The problem with the dataset is it doesn't tell you the name of the product. It only gives you the ID. There is a table though that has this information. Namely, the Products table. You'll notice that both tables have the Product ID variable, and you are able to join on this.
You can find the most popular product by counting the number of orders placed on each product .And the one with most number of order will be the most popular product.
Below script will give you the most popular product based on the the number of orders placed .
;WITH cte_1
AS(
SELECT p.ProductID,ProductName, count(OrderID) CNT
FROM Products p
JOIN [Order Details] od ON p.ProductID=od.ProductID
GROUP BY p.ProductID,ProductName)
SELECT top 1 ProductName
FROM cte_1
ORDER BY CNT desc
if you are using SQL server 2012 or any higher version, use 'with ties' for fetching multiple products having same order count.
;WITH cte_1
AS(
SELECT p.ProductID,ProductName, count(OrderID) CNT
FROM Products p
JOIN [Order Details] od ON p.ProductID=od.ProductID
GROUP BY p.ProductID,ProductName)
SELECT top 1 with ties ProductName
FROM cte_1
ORDER BY CNT desc
In your sample code,you tried to pull the product with maximum stock held. since you joined with other tables (like order details etc) you are getting multiple results for the same product. if you wanted to get a product with maximum stock,you can use any of the following script.
SELECT ProductName
FROM Products P
WHERE P.UnitsInStock = (SELECT MAX(P.UnitsInStock) Items
FROM Products P)
OR
SELECT top 1 ProductName
FROM Products P
ORDER BY P.UnitsInStock desc
OR
SELECT top 1 with ties ProductName --use with ties in order to pull top products having same UnitsInStock
FROM Products P
ORDER BY P.UnitsInStock desc
I have a product catalog with
a product table (tblProducts : ProductID),
a product category table (tblProductCategories : CatID),
a product sub-category table (tblProductSubCategories : SubCatID), and
a xref table (tblProdXCat : ProductID,CatID,SubCatID)
that links the products to cats and subcats.
Products can be linked to multiple cats and/or subcats.
How can I query and get distinct products only (no product duplicated in result set)?
Microsoft SQL Server please.
Thanks!
I assume your tblProducts table is a table of distinct products, so you aren't asking how to select distinct products from thence.
If you mean how to get distinct products from tblProdXCat, then it's probably as simple as SELECT DISTINCT ProductID FROM tblProdXCat.
But maybe you want a complete information about the products rather than simply their IDs. In that case you could just INNER JOIN that list of distinct ProductID values against tblProducts:
SELECT p.*
FROM Products p
INNER JOIN (SELECT DISTINCT ProductID FROM tblProdXCat) x
ON p.ProductID = x.ProductID
If that is still not what you want then you may need to clarify your request.
select distinct productID from tblProducts
Put all the joining ambiguity into the WHERE clause.
SELECT *
FROM Products
WHERE ProductID in
(
SELECT ProductId
FROM Products JOIN ...
)