SQL query for below data - mysql

For input, When quantity value greater then 1, convert in a new row with value 1 for quantity column.
INPUT
ID ProductFK Quantity Price
------------------------------------------------
10 1 2 100
11 2 3 150
12 1 1 120
OUTPUT
ID ProductFK Quantity Price
------------------------------------------------
10 1 1 100
10 1 1 100
11 2 1 150
11 2 1 150
11 2 1 150
12 1 1 120

We can do this using a sequence table trick. Inner join your current table to a sequence on the condition that the quantity be greater than or equal to the sequence value. For example:
SELECT t1.ID, t1.ProductFK, 1 AS Quantity, t1.Price
FROM yourTable t1
INNER JOIN (SELECT 1 AS Quantity UNION ALL SELECT 2 UNION ALL SELECT 3) t2
ON t1.Quantity >= t2.Quantity
ORDER BY t1.ID;
Demo

Related

Need help to group the available order details table to arrive at the distribution of count(order_line_item) , Qty and count(Qty)

I have a order table with the following information
Order ID, Product ID, Quantity ordered
OID PID Qty
1 10 1
1 20 2
2 10 2
2 40 4
3 50 1
3 20 3
4 30 1
4 90 2
4 90 5
5 10 2
5 20 2
5 70 5
5 60 1
6 80 2
If I run the following query
select `Qty`, count(`Qty`)
from `table`
group by `Qty`
I get the distribution of quantities in the table, which is
Qty count(`Qty`)
1 4
2 6
3 1
4 1
5 2
I want to find the distribution of quantity at order_line_item level too
That is how many orders which have one line item, had items with 1 quantity, 2 quantity and so one, something like
Count(Order_line_item) Qty Count(Qty)
1 2 1
2 1 2
2 2 2
2 3 1
2 4 1
3 1 1
3 2 1
3 5 1
4 1 1
4 2 2
4 5 1
What modification should i make in the above query to achieve this
Try this query
SELECT count_order_line_items, `Qty`, count(*)
FROM (
SELECT count(*) over (partition by `OID`) as count_order_line_items,
`Qty`
FROM Table1
) x
GROUP BY count_order_line_items, `Qty`
Demo: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=07dfb27a7d434eca1f0b9641aadd53c8
If your mysql version is less than 8 then try this one
SELECT count_order_line_items, `Qty`, count(*)
FROM Table1 t1
JOIN (
SELECT `OID`, count(*) as count_order_line_items
FROM Table1
GROUP BY `OID`
) t2 ON t1.`OID` = t2.`OID`
GROUP BY count_order_line_items, `Qty`
Demo: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=28c291a4693f31029a103f5c41a97d77

subtract from values by groups

What is the best way to subtract the lowest value from all values by group?
Something like:
ID Name Value
1 A 10
1 B 40
1 C 100
2 A 20
2 B 80
2 C 90
3 A 4
3 B 7
3 C 8
turn to:
ID Name Value
1 A 0
1 B 30
1 C 90
2 A 0
2 B 60
2 C 70
3 A 0
3 B 3
3 C 4
Use window functions:
select id, name, value - min(value) over (partition by id) as
from t;
If you actually want to update the values, in MySQL, aggregation and join are probably the simplest solution:
update t join
(select id, min(value) as min_value
from t
group by id
) tt
on t.id = tt.id
set value = value - min_value
where min_value <> 0;

Merging Multiple Queries - Same Table

I have 1 table called itemmovement : It has Item Id , Quantity In , Quantity Out , Invoice Id, Date. I need to make in one query to show how many pieces are sold and beside the sold column there will be the current on hand quantity .
itemmovement
Id itemid qtyin qtyout invid purchasereturnid date
1 1 10 2019-01-04
2 2 8 2019-01-06
3 2 2 1 2019-01-08
4 1 3 2 2019-01-12
5 2 1 2019-02-04
6 3 4 2019-03-04
7 1 1 3 2019-04-04
8 1 1 1 2019-04-14
9 3 1 2 2019-04-24
I need the query to show this result
Id itemid Sold Quantity OnHandQty
1 1 4 5
2 2 2 7
3 3 0 3
I'm Trying to use this query but not working
SELECT *
FROM
(SELECT itmv.itemid,
sum(itmv.qtyout)-sum(itmv.qtyin)
FROM itemmovement itmv
WHERE (itmv.systemdate BETWEEN '2019-01-01' AND '2019-06-01')
AND invid>0
GROUP BY itmv.itemid) AS result1,
(SELECT sum(itmv2.qtyin)-sum(itmv2.qtyout)
FROM itemmovement itmv2
WHERE itmv.itemid=itmv2.itemid
GROUP BY itmv2.itemid) AS result2
ORDER BY sum(itmv.qtyin)-sum(itmv.qtyout)
I'm getting :
Unknown column 'itmv.itemid' in 'where clause it for this syntax :
where itmv.itemid = itmv2.itemid
Here's your query.
select itemid
, sum(case when COALESCE(invid,0) > 0 then qtyout else 0 end) as Sold_Qantity
, sum(qtyin)-sum(qtyout) as OnHandQty
from itemmovement
group by itemid

How to sort & group by sql query?

I have Data
id Date CatId itemid itemname price
1 10/5/2019 1 1 ABC 20
2 10/5/2019 1 2 XYZ 30
3 10/5/2019 2 1 ABC 20
4 10/5/2019 3 1 ABC 20
5 11/5/2019 1 2 XYZ 30
6 11/5/2019 2 1 ABC 20
7 11/5/2019 2 3 PQR 40
8 12/5/2019 3 1 ABC 20
9 12/5/2019 3 2 XYZ 30
10 12/5/2019 1 2 XYZ 30
11 12/5/2019 2 1 ABC 20
expected result data
date CatId toal
10/5/2019 1 50
10/5/2019 2 20
10/5/2019 3 20
11/5/2019 1 30
11/5/2019 2 60
12/5/2019 1 30
12/5/2019 2 20
12/5/2019 3 50
I want result order by date and after sum of price group by catid,
I have tried multiple query applied but get exact solution. I have spent so much time.
I have tried bellow queries
SELECT * FROM (SELECT * FROM `table` ORDER BY `date` DESC) as tbl
GROUP BY tbl.`catid`
SELECT *
FROM `table`
GROUP BY `date` ORDER BY `date` DESC
SELECT *
FROM (
SELECT * FROM `table`
ORDER BY `date` DESC
) AS sub
GROUP BY `catid` ORDER BY `date` DESC
the columns you can use in order by and group by can be different
You could use group by and sum directly
select date, catid, sum(price)
from my_table
group by date, catid
order by date, sum(price), catid

MySQL Group By not producing expected result

This is my table structure:
rec_id product_id quantity quantity_in quantity_out balance stock_date status
1 2 342 NULL 17 325 2009-10-23 1
2 2 325 NULL 124 201 2009-10-23 1
3 1 156 NULL 45 111 2009-10-23 1
4 2 201 NULL 200 1 2009-10-23 1
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
All I want is the last transaction done for a given product: product_id, quantity, quantity_out and balance from this table.
Example, there are 2 transaction done for product 2 (ids 1 & 2):
final balance for product_id 2 is 0 -> stored in rec_id 5
final balance for product_id 1 is 76 -> stored in rec_id 6
Final result/output should be like this:
recid productid quantity quantityin quantityout balance stock_date status
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
You can find the latest record for each product like:
select max(rec_id) as MaxRec
from YourTable
group by product_id
Using a subquery, you can retrieve the latest rows for their product:
select *
from YourTable
where rec_id in (
select max(rec_id) as MaxRec
from YourTable
group by product_id
)
Here's a single query with no subqueries:
SELECT main.*
FROM YourTable main
LEFT JOIN YourTable newer
ON newer.product_id = main.product_id AND newer.rec_id > main.rec_id
WHERE newer.rec_id IS NULL;
You can tweak the field list however you want--make sure you select fields from main, not newer, which should be all null.