I have a product-table and a table containing all parts of a product and the quantity.
Structure of products table:
id
name
Structure of parts table:
id
productsId
partsId
quantity
Now I want to get all products and for every product the total quantity parts and quantity of different parts . The current solution is this query:
SELECT
products.*,
(
SELECT count(quantity)
FROM product_has_part
WHERE product_has_part.productsId = products.id
) AS partsQty,
(
SELECT sum(quantity)
FROM product_has_part
WHERE product_has_part.productsId = products.id
) AS sumQty
FROM products
Now I have to subselects across the same table. So I think there must be a better way to create this query?
use join
Select *,count(quantity),sum(quantity)
From products p join
product_has_part pp on pp.productsId = p.id
FROM products
or Group by use for count or sum for each id
Select *,count(quantity),sum(quantity)
From products p join
product_has_part pp on pp.productsId = p.id
FROM products
Group by p.id
p.f1, p.f2, p.f3 mean each field of p.
select p.f1, p.f2, p.f3 ... count(php.quantity), sum(php.quantity)
from products p
join product_has_part php
on p.productsId = php.productsId
group by p.f1, p.f2, p.f3 ..
Related
we have a products table with let's say has this structure,
id, name, price, status
and we have another table called product_meta which we created to store additional fields for products that we cannot add to the products table. product meta has a structure like
id, product_id, key, value
so let's say in the products table we have
id, name, price, status
1, test, 100, active
Then in the meta
id, product_id, key, value
1, 1, is_delivered, yes
How do I write the query to inner join the products to meta if I want to select all products which don't have the is_delivered or if there is, the is_delivered should have a value of no
SELECT *
FROM products p
INNER JOIN product_meta m ON p.product_id = m.product_id
WHERE m.is_delivered IS NULL OR m.is_delivered ='no'
Please consider using LIMIT, ORDER BY, GROUP BY if necessary.
I would use a left join, like so:
SELECT
p.id, p.name -- add other fields when needed
FROM
products AS p
LEFT JOIN
product_meta AS m
ON
m.product_id = p.id AND m.key = 'is_delivered'
WHERE
m.id IS NULL OR m.value = 'no'
By using the filter on [key] in the join you only get the records where "is_delivered" is set, so you can do exactly whay you want with the query-result: filter on "key not set" or "key has no".
I am looking for a way to calculate stock quantity from two tables.
My table records are as follows:
Below is my product table
I have two table first is "stockinward" for purchase the stock and another is stockoutward for sale out the stock.
Below is the screenshot for stockinward table
and here is the screenshot for stockoutward
Below is my query to calculate the stock
SELECT
p.Id,
p.Name,
p.UnitPrice,
((SELECT
IFNULL(SUM(Quantity), 0)
FROM
stockinward
WHERE
ProductId = p.Id) - (SELECT
IFNULL(SUM(Quantity), 0)
FROM
stockoutward
WHERE
ProductId = p.Id)) AS Quantity
FROM
product p;
But the issue is in above query, when i have more then 1000 products it takes more then 8 second, so is there any other way in which i get the same result in 1 or 2 seconds?
Thanks in advance :)
You could also use joins instead of subqueries
SELECT
p.Id,
p.Name,
p.UnitPrice,
IFNULL(qin.Quantity, 0) - IFNULL(qout.Quantity, 0) AS Quantity
FROM product
LEFT JOIN (
SELECT ProductId, SUM(Quantity) AS Quantity
FROM stockinward
GROUP BY ProductId
) qin ON p.Id = qin.ProductId
LEFT JOIN (
SELECT ProductId, SUM(Quantity) AS Quantity
FROM stockoutward
GROUP BY ProductId
) qout ON p.Id = qout.ProductId
I have a situation where a LEFT JOIN is not going far enough in what I need to accomplish. I have a product table (Products with columns ItemID, ProductName, Price) and an order table (Orders with columns OrderNumber, ItemID, Quantity).
I need the query to return all of the products from the Products table that are not currently a part of a specific order (for example, list all products that are not a part of OrderNumber 52).
My current query lists all of the products but excludes the products that are a part of ANY OrderNumber.
$query = "SELECT Products.ItemID, Products.ProductName
FROM Products
LEFT JOIN Orders
ON Orders.ItemID = Products.ItemID
WHERE Orders.ItemID IS NULL
ORDER BY Products.ProductName";
You can use a anti-join for this purpose, like so:
SELECT ItemID, ProductName
FROM Products
WHERE ItemID NOT IN (
SELECT ItemID
FROM Orders
WHERE OrderID = X
)
ORDER BY ProductName
SELECT Products.ItemID, Products.ProductName
FROM Products
WHERE Products.ItemID not in (select Orders.ItemID from Orders where Orders.OrderNumber = xxx)
ORDER BY Products.ProductName
What you need can be easily accomplished just by adding the order number in the join condition:
SELECT Products.ItemID, Products.ProductName
FROM Products
LEFT JOIN Orders
ON (Orders.ItemID = Products.ItemID AND OrderNumber = 52)
WHERE Orders.ItemID IS NULL
ORDER BY Products.ProductName
I have three MySql tables:-
tbl_part - Contains a list of parts with a part_id
tbl_product - Contains a list of products with a product_id
tbl_part_to_product - Contains one to many relationships between parts and products (part_id & product_id)
I'm trying to do two things:-
Select all products that only have one part.
Find all products that only have a specific part as there only part.
SELECT
*
FROM
tbl_part part
INNER JOIN tbl_part_to_product p2p ON part.part_id = p2p.part_id
INNER JOIN tbl_product prod ON p2p.product_id =prod.product_id
WHERE part.name = 'whatever'
GROUP BY prod.product_id
HAVING COUNT(*) = 1
To select all products that only have one part just delete the WHERE clause.
If you don't want to join to the parts table:
SELECT
*
FROM
tbl_product prod
INNER JOIN tbl_part_to_product p2p ON p2p.product_id =prod.product_id
GROUP BY prod.product_id
HAVING COUNT(*) = 1
Let's address both questions:
Select all products that only have one part.
SELECT tbl_product.*
FROM
tbl_product product
INNER JOIN tbl_part_to_product ptop ON ptop.product_id = product.product_id
GROUP BY product.product_id
HAVING COUNT(ptop.part_id) = 1
Find all products that only have a specific part as there only part.
SELECT tbl_product.*
FROM
tbl_product product
INNER JOIN tbl_part_to_product ptop ON ptop.product_id = product.product_id
INNER JOIN tbl_part part ON ptop.part_id = part.part_id
WHERE part.part_name = 'some name'
GROUP BY product.product_id
HAVING COUNT(ptop.part_id) = 1
If you get GROUPing errors from either query, you need to add all the tbl_product fields to the GROUP.
I have a query that I feel is very bulky and can do with optimisation. First thing would obviously be replacing not in subquery with join but it affects the sub-sub query that I have. I'd appreciate suggestions/workaround on it.
This is the query
SELECT *
FROM lastweeksales
WHERE productID = 1234
AND retailer NOT
IN (
SELECT retailer
FROM sales
WHERE productID
IN (
SELECT productID
FROM products
WHERE publisher = 123
)
AND DATE = date(now())
)
Basically, I want to get rows from lastweek's sales on a product where retailers are not present that did sales today but sales should only be on products by a certain publisher.
:S:S:S
You can group together 2 inner subqueries easily via INNER JOIN. For the outer one you should use LEFT OUTER join and then filter on retailer IS NULL, like this:
SELECT lws.*
FROM lastweeksales lws
LEFT JOIN (SELECT s.retailer
FROM sales s
JOIN products p USING (productID)
WHERE p.publisher = 123
AND s.date = date(now())) AS r
ON lws.retailer = r.retailer
WHERE r.retailer IS NULL;