I have a table for product, sales_item and a stock with following structure
Product table:
+----+-----+-------------+
| id |name |description |
+----+-----+-------------+
| 1 |Pr1 |prod1 |
+----+-----+-------------+
| 2 |Pr2 |prod2 |
+----+-----+-------------+
| .. |... |..... |
+----+-----+-------------+
sales_item_details table
+-----+----------+------------+-----+
| id | sales_id | product_id | qty |
+-----+----------+------------+-----+
| 517 | 211 | 1 | 200 |
+-----+----------+------------+-----+
| 518 | 211 | 1 | 120 |
+-----+----------+------------+-----+
and production
+----+------------+-------+
| id | product_id | qty |
+----+------------+-------+
| 1 | 1 | 20 |
| 2 | 2 | 200 |
| 3 | 1 | 20 |
| 4 | 3 | 30 |
| 5 | 9 | 30 |
| 6 | 65 | 10 |
| 7 | 65 | 50 |
| 8 | 71 | 10 |
| 9 | 71 | 10 |
| 10 | 71 | 10 |
+----+------------+-------+
And now I am creating multiple database with same table defination and need to maintain stock
production table and product table will be maintained from single database
only sales_item_details table will be different but product id will same
So how will be the query to get SUM(qty) of sales item details and view the inventory in stock
I have tried this:
SELECT
`pr`.`id`,
`pr`.`name`,
sl.size,
IFNULL(SUM(s.qty), 0) AS sales,
IFNULL((SELECT SUM(qty) FROM production st WHERE st.product_id = `pr`.`product-id`), 0) AS stock_added
FROM products pr
LEFT JOIN (
SELECT qty, product_id FROM db1.sales_item_details
UNION ALL
SELECT qty, product_id FROM db2.sales_item_details
) s ON pr.`id` = s.product_id
LEFT JOIN size_list sl ON sl.id = `pr`.`product-size`
GROUP BY s.product_id
ORDER BY sales DESC
but getting the product which is sold
Any help will be appriciated
1st I created a view holding all sales items grouped by product id in the main database:
CREATE OR REPLACE VIEW unit_sold_all AS
SELECT
p.`product-id` AS product_id,
(
(SELECT IFNULL(SUM(s0.qty), 0) FROM db_1.sales_item_details s0 WHERE s0.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s1.qty), 0) FROM db_2.sales_item_details s1 WHERE s1.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s2.qty), 0) FROM db_3.sales_item_details s2 WHERE s2.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s3.qty), 0) FROM db_4.sales_item_details s3 WHERE s3.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s4.qty), 0) FROM db_5.sales_item_details s4 WHERE s4.product_id = p.`product-id`)
) as total_unit_sales
FROM products p
Then in another sql, I selected the sum of the sales.
PS: I answered this question myself because this might need by another person in the future.
Related
I have the following tables:
Customer
| c_id | name |
| -------- | -------------- |
| 1 | Adam |
| 2 | Bradley |
| 3 | Chandler |
| 4 | Damian |
| 5 | Eric |
| 6 | Frank |
orders
| order_id | c_id | amount
| -------- | -------------- | -------------- |
| 1 | 1 | 50
| 2 | 1 | 2
| 3 | 2 | 15
| 4 | 2 | 22
| 5 | 2 | 10
| 6 | 2 | 7
| 7 | 3 | 7
| 8 | 3 | 2
| 9 | 5 | 18
| 10 | 5 | 24
| 11 | 6 | 60
| 12 | 6 | 1
I want to create a list of users who have order amounts over 50.
This list should include c_id, name and the sum of all their orders including those under 50.
so it should look like this:
| c_id | name | amount
| -------- | -------------- | -------------- |
| 1 |Adam | 52
| 6 | Frank | 61
You can use group by and having:
select c.c_id, c.name, sum(o.amount)
from orders o join
customers c
on o.c_id = c.c_id
group by c.c_id, c.name
having max(o.amount) > 50;
SELECT
c_id
, name
, SUM(amount) AS total_amount
FROM
orders a
INNER JOIN customer b
ON b.c_id = a.user_id
WHERE
c_id IN (
SELECT
user_id
FROM
orders
WHERE
amount >= 50)
GROUP BY c_id, name
Best to break this down into chunks:
Customers who have a total amount over 50:
SELECT user_id FROM orders GROUP BY user_id HAVING sum(amount) >= 50;
Sum of the amounts for each order for customers that meet the criteria above:
SELECT user_id, sum(amount) as order_total
FROM orders
WHERE user_id IN (SELECT user_id FROM orders HAVING sum(amount) >= 50 GROUP BY user_id)
GROUP BY user_id;
You can just join over to your customer table to grab the name. Didn't include since that is the more straightforward ask here.
I have the following table:
product
+-------------+------------+
| id_product | quantity |
+-------------+------------+
| 15 | 0 |
| 16 | 1 |
| 17 | 3 |
| 18 | 1 |
+-------------+------------+
And the other table is a subquery
+------------+-----------+
| id_product | total |
+------------+-----------+
| 15 | 1 |
| 17 | 1 |
| 18 | 4 |
+------------+-----------+
And I want to do is in a single update query, update the table products with the records returned by the subquery, making a sum, I can get one or many records from the subquery.
+-------------+------------+
| id_product | quantity |
+-------------+------------+
| 15 | 1 |
| 16 | 1 |
| 17 | 4 |
| 18 | 5 |
+-------------+------------+
I tried to make this update query, but it does not do what I want.
UPDATE product p
INNER JOIN (
SELECT id_product, count(*) as total
FROM othertable
GROUP BY id_product
) c ON p.id_product = c.id_product
SET p.quantity = c.total;
______EDIT______
UPDATE product p
INNER JOIN (
SELECT id_product, count(*) as total
FROM othertable
GROUP BY id_product
) c ON p.id_product = c.id_product
SET p.quantity = p.quantity + c.total
I have 3 tables:
table products
table sub products
table stock.
I want to join these tables like in the result table below. In fact, I want All products that have least price and have count greater than zero and inserted as latest records!
How can I do the query?
more explain:
table product
----------------------------------
pid | title | desc | content |
----------------------------------
1 | lumia 920| ..... | ...... |
----------------------------------
2 | galaxys6 | .... | ...... |
----------------------------------
table sub_product
------------------------
subid |pid| name |
------------------------
1 | 1 | yellow |
------------------------
2 | 1 | black |
------------------------
3 | 2 | 32 GB |
table stock
-----------------------------------------------
sid |subid| price | count | inserted_date |
-----------------------------------------------
1 | 1 | 100 | 5 | 2015-01-01 |
-----------------------------------------------
2 | 1 | 150 | 9 | 2015-01-02 |
-----------------------------------------------
3 | 1 | 100 | 0 | 2015-02-02 |
-----------------------------------------------
4 | 2 | 111 | 1 | 2015-02-21 |
-----------------------------------------------
5 | 3 | 50 | 7 | 2015-02-01 |
-----------------------------------------------
6 | 3 | 10 | 4 | 2015-03-06 |
-----------------------------------------------
7 | 3 | 400 | 9 | 2015-06-06 |
-----------------------------------------------
table result
------------------------------------------------------------
pid |subid| title | name | price | count | inserted_date
------------------------------------------------------------
1 | 2 |lumia 920| black | 111 | 1 | 2015-02-21
------------------------------------------------------------
2 | 3 |galaxy s6| 32 GB | 10 | 4 | 2015-03-06
------------------------------------------------------------
as you see in product table we have two items lumia 920 and galaxy s6
and in sub_product we have 3 items that related to products.
also in stock I saved all modication of price and count of each item
so I want return latest modification of each sub_product as current state of it sub_prodct that has least price as result
but if count was zero should return another sub_product with mentioned conditions.
Select * From stock s Join sub_product sp On s.sub_productid = sp.sub_productid Join product p On p.productid = sp.productid
Where s.counte > 0 And s.date_insert in (Select MAX(date_insert) as d From stock ss
where s.sub_productid = ss.sub_productid group by sub_productid)
This query will return the all products that have least price and have count greater than 0 and latest records.
SELECT p.pid, sp.subid, p.title, sp.name, s.price, s.count, s.inserted_date
FROM product p
INNER JOIN sub_product sp ON sp.pid = p.pid
INNER JOIN stock s ON s.subid = sp.subid
WHERE s.count > 0
GROUP BY p.title
ORDER BY s.inserted_date DESC, s.price ASC
Try something like this:
SELECT prod.title, prod.desc, subProd.spid, subProd.pid, subProd.name, stk.price, stk.discount, stk.count, stk.inserted_date
FROM products AS prod
INNER JOIN sub_products AS subProd ON prod.pid = subProd.pid
INNER JOIN stock AS stk ON subProd.spid = stk.spid
AND stk.count > 0
AND stk.spid = (select spid from stock order by inserted_date desc limit 1)
I have a many to many relationship, Orders, OrderProducts, and Products. I need a query that gives me a list of products that are NOT in ALL orders, but has been ordered.
______________________
| ORDERS |
_______________________
| OrderID | OrderDate |
| 1 | 1/2/2012 |
| 2 | 1/3/2012 |
| 3 | 1/4/2012 |
| 4 | 1/5/2012 |
| 5 | 1/6/2012 |
______________________
| ORDERPRODUCTS |
_______________________
| OrderID | PRODUCTID |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 1 |
| 3 | 5 |
| 4 | 1 |
| 5 | 1 |
__________________________
| PRODUCTS |
__________________________
| PRODUCTID | PRODUCTNAME |
| 1 | Widget 1 |
| 2 | Widget 2 |
| 3 | Widget 3 |
| 4 | Widget 4 |
| 5 | Widget 5 |
| 6 | Widget 6 |
In the provided example, notice that product 1 is in all orders and product 6 is not ordered at all.
I need a query that returns Products 2, 3, 4, and 5.
Also keep in mind that while there aren't many products, there are a few hundred thousand orders in the live database.
SELECT PRODUCTID
FROM ORDERPRODUCTS
GROUP BY PRODUCTID
HAVING COUNT(DISTINCT OrderID) < (SELECT COUNT(*) FROM ORDERS )
It's Saturday night, so this is probably not the most elegant, but here's one try:
DECLARE #OrderProducts TABLE(OrderID INT, ProductID INT);
DECLARE #Products TABLE(ProductID INT, ProductName VARCHAR(32));
INSERT #Products VALUES
(1,'Widget 1'),(2,'Widget 2'),
(3,'Widget 3'),(4,'Widget 4'),
(5,'Widget 5'),(6,'Widget 6');
INSERT #OrderProducts VALUES
(1,1),(1,2),(2,1),(2,2),(2,3),
(2,4),(3,1),(3,5),(4,1),(5,1);
SELECT p.ProductID, p.ProductName
FROM #Products AS p
WHERE EXISTS -- had been ordered at least once
(
SELECT 1 FROM #OrderProducts
WHERE ProductID = p.ProductID
)
AND EXISTS -- at least one order does NOT include it
(
SELECT 1 FROM #OrderProducts AS o
WHERE NOT EXISTS
(
SELECT 1 FROM #OrderProducts AS o2
WHERE o2.OrderID = o.OrderID
AND o2.ProductID = p.ProductID
)
);
SELECT
DISTINCT
PossibleOrderProducts.PRODUCTID
FROM
(
SELECT
Orders.ORDERID,
Products.PRODUCTID
FROM
ORDERS Orders
CROSS JOIN
(
SELECT DISTINCT PRODUCTID FROM ORDERPRODUCTS
) Products
) PossibleOrderProducts
LEFT JOIN ORDERPRODUCTS ActualOrderProducts ON
ActualOrderProducts.ORDERID = PossibleOrderProducts.ORDERID
AND ActualOrderProducts.PRODUCTID = PossibleOrderProducts.PRODUCTID
WHERE
ActualOrderProducts.ORDERID IS NULL
Is there any way to return distinct values with blank/null data from a table join. Best to explain with my example below.
Table "orders"
order_id | order_total
1 | 10
2 | 20
3 | 50
Table "order_items"
item_id | order_id | name | qty_ordered | base_price | row_total
1 | 1 | Product | 1 | 10 | 10
2 | 2 | Product | 1 | 10 | 10
3 | 2 | Product2 | 1 | 10 | 10
4 | 3 | Product | 2 | 10 | 20
5 | 3 | Product2 | 3 | 10 | 30
I'm trying to produce a result set that looks like this.
order_id | item_id | name | qty_ordered | base_price | row_total | order_total
1 | 1 | Product | 1 | 10 | 10 | 10
2 | 2 | Product | 1 | 10 | 10 | 20
null | 3 | Product2 | 1 | 10 | 10 | null
3 | 4 | Product | 2 | 10 | 20 | 50
null | 5 | Product2 | 3 | 10 | 30 | null
I only want the order_id and order_total once per order. I figure this is possible with some sort of join/distinct/sub query but alas nothing I've tried has worked so far.
Use:
SELECT x.order_id,
x.item_id,
x.name,
x.qty_ordered,
x.base_price,
x.row_total,
x.order_total
FROM (SELECT CASE
WHEN #order = o.order_id THEN NULL
ELSE o.order_id
END AS order_id,
oi.item_id,
oi.name,
oi.qty_ordered,
oi.base_price,
oi.row_total,
o.order_total,
CASE
WHEN #order = o.order_id THEN NULL
ELSE o.order_total
END AS order_total,
#order := o.order_id
FROM ORDER_ITEMS oi
JOIN ORDERS o ON o.order_id = oi.order_id
JOIN (SELECT #order := -1) r
ORDER BY o.order_id, oi.item_id) x
SELECT * FROM order_items
LEFT JOIN orders
ON (
order_items.order_id=orders.order_id
AND
order_items.item_id=(
SELECT MIN(item_id)
FROM order_items a
WHERE a.order_id=order_items.order_id
)
)
This should work because the nested query always returns the same MIN(item_id) for each order, and it only joins for that item.
But this is a very, very ugly piece of sql. Don't do this.