subtract two column from different table and group by id and id - mysql

after two week search i couldn't write this query please help me
NOTE
TABLE 1 sum(quantity_box) group by id_p and id_w
TABLE 2 sum(quantity_box) group by id_p and id_w
then
TABLE1.sum(quantity_box)- TABLE2.sum(quantity_box) where id_p = id_p and id_w = id_w
table 1 ) wherehouseproduct_add id = id_w
id | name
10 | warehouse1
20 | warehouse2
table2) wherehouse_products
id | id_w |id_p |quantity_box
1 | 10 | 2 | 10
2 | 10 | 2 | 50
3 | 20 | 3 | 100
4 | 20 | 1 | 20
5 | 20 | 1 | 10
6 | 10 | 1 | 10
7 | 10 | 3 | 10
table3) wherehouse_products_sell
id | id_w |id_p |quantity_box
1 | 10 | 2 | 50
2 | 20 | 3 | 30
3 | 20 | 1 | 20
table4) products
id_p | product_name
1 | snack
2 | watebottle
3 | headphone
i want to output like
id_w | id_p | product_name| total_quantity_box
10 | 1 | snack |10
10 | 2 | watebottle |10
10 | 3 | headphone |10
20 | 1 | snack |10
20 | 2 | watebottle |10
20 | 3 | headphone |70

Calculate each type of sum individually in sub selects and join them as per your criteria then do your calculations in outer select
select wp.id_w,
wp.id_p,
wp.quantity - wps.quantity total_quantity_box
from
(select id_w,id_p,sum(quantity_box) quantity from wherehouse_products group by id_w,id_p) wp
join
(select id_w,id_p,sum(quantity_box) quantity from wherehouse_products_sell group by id_w,id_p) wps
using(id_w,id_p)
DEMO

Related

GROUP sum BY two tables by joining

I'm trying to write a SQL query that will correctly group sales items sold_qyt and sub-total-price together as per product's category so I can show this on the printable invoice that product from Jelly Sheet = 4 at a rate of 62 subtotal for this category product is 248(4 * 62 = 248). but when I try to run the below-mentioned query it shows out-put as 12 but I want subtotal and sold_qyt segregated base on category.
I have tried to run different queries just one query gives the output which is mentioned below and this is for just the sum of all sold_qyt. DB example is also shown below
DB Example: (For better understanding)
Table # 1:
Category
ID | code | name
1 | 1 | jelly sheet
2 | 2 | 9D Glass
3 | 3 | Polished Glass
Table # 2:
Product:
ID | code | name | cost | category_id | price
1 | 1 | IP11JS | 50 | 1 | 62
2 | 2 | IP12JS | 50 | 1 | 62
3 | 3 | IP119D | 40 | 2 | 55
4 | 4 | IP129D | 40 | 2 | 55
5 | 5 | IP11PG | 18 | 3 | 25
6 | 6 | IP12PG | 18 | 3 | 25
Table # 3:
sale_items:
ID | sale_id | product_id | product_code | product_name | unit_price | sold_qyt | subtotal |
1 | 1 | 1 | 1 | IP11JS | 62 | 2 | 124 |
2 | 1 | 2 | 2 | IP12JS | 62 | 2 | 124 |
3 | 1 | 3 | 3 | IP119D | 55 | 2 | 110 |
4 | 1 | 4 | 4 | IP129D | 55 | 2 | 110 |
5 | 1 | 5 | 5 | IP11PG | 25 | 2 | 50 |
6 | 1 | 6 | 6 | IP12PG | 25 | 2 | 50 |
7 | 2 | 7 | 1 | IP11JS | 62 | 2 | 124 |
8 | 2 | 8 | 2 | IP12JS | 62 | 2 | 124 |
9 | 2 | 9 | 3 | IP119D | 55 | 2 | 110 |
10 | 2 | 10 | 4 | IP129D | 55 | 2 | 110 |
11 | 2 | 11 | 5 | IP11PG | 25 | 2 | 50 |
12 | 2 | 12 | 6 | IP12PG | 25 | 2 | 50 |
SQL Query which is run by me:
SELECT sale_id,
SUM(sold_qyt) AS sold_qyt
FROM sale_items
GROUP BY sale_id
kindly help me with this difficulty thanks in advance
Update: 1-21-2021
i execute new query
SELECT (sma_sale_items.sale_id, sma_categories.code AS sma_products.category_id, sma_products.code AS sma_sale_items.product_code,)
SUM(sold_qyt) AS sold_qyt
SUM(subtotal) AS subtotal
FROM sma_sale_items
LEFT JOIN sma_products ON sma_products.id=sma_sale_items.product_id
LEFT JOIN sma_categories ON sma_categories.code=sma_products.category_id
GROUP BY sma_sale_items.sale_id
ORDER BY sma_categories
but no luck :(
I want the output like this:
Expected OUT PUT:
ID | sale_id | category_name | sold_qyt | subtotal |
1 | 1 | Jelly Sheet | 4 | 248 |
2 | 1 | 9D Glass | 4 | 220 |
3 | 1 | Polished Glass | 4 | 100 |
4 | 2 | Jelly Sheet | 4 | 248 |
5 | 2 | 9D Glass | 4 | 220 |
6 | 2 | Polished Glass | 4 | 100 |
The ID column in your expected result set is very misleading - it appears to be just new ID value for the output result set rather than any of the ID values from the source tables.
If it is important for you then you can use this query:
SELECT ROW_NUMBER() OVER (ORDER BY sale_id, category_id),
sale_id,
category_name,
sold_qty,
subtotal
FROM (
SELECT c.ID as category_id,
si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY c.ID,
si.sale_id,
c.[name]
) r
If it is not relevant and you only want the sale_id, category_name and the totals then simplify it to:
SELECT si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY si.sale_id,
c.[name]
ORDER BY sale_id, category_name

sum in table then subtract with different table

after two week try i couldn't write this query please help me
NOTE
TABLE 1 sum(quantity_box) group by id_p and id_w
TABLE 2 sum(quantity_box) group by id_p and id_w
then
TABLE1.sum(quantity_box)- TABLE2.sum(quantity_box) where id_p = id_p and id_w = id_w
table 1 ) wherehouseproduct_add id = id_w
id | name
10 | warehouse1
20 | warehouse2
table2) wherehouse_products
id | id_w |id_p |quantity_box
1 | 10 | 2 | 10
2 | 10 | 2 | 50
3 | 20 | 3 | 100
4 | 20 | 1 | 20
5 | 20 | 1 | 10
6 | 10 | 1 | 10
7 | 10 | 3 | 10
table3) wherehouse_products_sell
id | id_w |id_p |quantity_box
1 | 10 | 2 | 50
2 | 20 | 3 | 30
3 | 20 | 1 | 20
table4) products
id_p | product_name
1 | snack
2 | watebottle
3 | headphone
i want to output like
id_w | id_p | product_name| total_quantity_box
10 | 1 | snack |10
10 | 2 | watebottle |10
10 | 3 | headphone |10
and
id_w | id_p | product_name| total_quantity_box
20 | 1 | snack |10
20 | 2 | watebottle |10
20 | 3 | headphone |70
for now i used
select wp.id_w,
wp.id_p,
wp.quantity - wps.quantity total_quantity_box
from
(select id_w,id_p,sum(quantity_box) quantity from warehouse_products group by id_w,id_p) wp
join
(select id_w,id_p,sum(quantity_box) quantity from warehouse_products_sell group by id_w,id_p) wps
using(id_w,id_p)
You need to use LEFT JOIN so you'll get results for products that aren't in wherehouse_products_sell.
select wp.id_w, wp.id_p, p.product_name,
wp.quantity - IFNULL(wps.quantity, 0) total_quantity_box
from
(select id_w,id_p,sum(quantity_box) quantity from warehouse_products group by id_w,id_p) wp
left join
(select id_w,id_p,sum(quantity_box) quantity from warehouse_products_sell group by id_w,id_p) wps
using(id_w,id_p)
join products AS p ON wp.id_p = p.id_p

need help a query in sql server 2008

Hi I have doubt in sql server
Table : patient
patientno | refdoctor| loccode | status | sdate
100 | 31 |10 | 1 | 2012-05-03
100 | 32 |10 | 1 |1997-02-04
100 | 36 |10 | 1 |2014-09-16
100 |35 |10 | 1 |2013-05-03
100 | 50 |10 | 1 | 1988-05-08
100 | 20 |10 | 2 |2015-02-05
Table : targetpatient
patientno | refdoctor| loccode | status | sdate
100 | 21 | 10 | 2 | 2004-05-18
100 | 23 | 10 | 2 |2005-07-25
100 | 24 | 10 | 2 | 2006-06-22
100 | 26 | 10 | 2 |2012-05-14
100 | 28 |10 | 2 |2013-05-03
100 |29 |10 | 2 | 2014-09-26
100 | 33 | 10 | 2 | 2012-10-22
100 | 39 | 10 | 2 |2002-12-13
100 |41 | 10 | 2 |2012-05-13
Here I want output patient table relates status
statusvalue=5's sdate is less than or equal to checkvalue=2's sdate and
the difference between the dates should be less than 30days then given count
if that condition not fall then count must be return zero(0)
select o.patientno,o.loccode,o.status,o.sDate, count(*) as cnt
from patient o join targetpatient t on o.patientno=t.patientno and o.loccode=t.loccode and o.status in('1') and t.status in('2') and
o.sDate<=t.sdate
and datediff(dd,o.sdate,t.sdate)<=30
group by o.patientno,o.loccode,o.status,o.sDate
based on above query I got result like below:
patientno | loccode | status | sdate | count
100 | 10 | 1 |2012-05-03 | 2
100 | 10 | 1 |2013-05-03 | 1
100 | 10 | 1 |2014-09-16 | 1
but I want expected result like below
patientno | loccode | status | sdate | count
100 | 10 | 1 |2012-05-03 | 2
100 | 10 | 1 |2013-05-03 | 1
100 | 10 | 1 |2014-09-16 | 1
100 | 10 | 1 | 1997-02-04 | 0
100 | 10 |1 | 1988-05-08 | 0
please tell me how to write query to achive this task in sql server .
If you want to include the records that doesn't have any matches in the joined table you'll want to use a left join instead and do the count on a column in the joined table instead like this:
select o.patientno,o.loccode,o.status,o.sDate, count(t.sdate) as cnt
from patient o
left join targetpatient t on o.patientno = t.patientno
and o.loccode = t.loccode
and o.status in('1')
and t.status in('2')
and o.sDate <= t.sdate
and datediff(dd,o.sdate,t.sdate) <= 30
group by o.patientno,o.loccode,o.status,o.sDate
A left join will return all rows from the table on the left side (patient in your case) plus the matching rows from the right-hand side table. The rows that doesn't have any matches in the right-hand side table will get null as values.

Filter out closest duplicated rows (but not completely all) from MySQL table

In table I need to filter out nearest duplicated rows which have same status_id (but not completely all) when user_id is the same. GROUP BY or DISTINCT did not help in this situation. Here is an example:
---------------------------------------------------
| id | user_id | status_id | date |
---------------------------------------------------
| 1 | 10 | 1 | 2010-10-10 10:00:10|
| 2 | 10 | 1 | 2010-10-11 10:00:10|
| 3 | 10 | 1 | 2010-10-12 10:00:10|
| 4 | 10 | 2 | 2010-10-13 10:00:10|
| 5 | 10 | 4 | 2010-10-14 10:00:10|
| 6 | 10 | 4 | 2010-10-15 10:00:10|
| 7 | 10 | 2 | 2010-10-16 10:00:10|
| 8 | 10 | 2 | 2010-10-17 10:00:10|
| 9 | 10 | 1 | 2010-10-18 10:00:10|
| 10 | 10 | 1 | 2010-10-19 10:00:10|
Have to look like:
---------------------------------------------------
| id | user_id | status_id | date |
---------------------------------------------------
| 1 | 10 | 1 | 2010-10-10 10:00:10|
| 4 | 10 | 2 | 2010-10-13 10:00:10|
| 5 | 10 | 4 | 2010-10-14 10:00:10|
| 7 | 10 | 2 | 2010-10-16 10:00:10|
| 9 | 10 | 1 | 2010-10-18 10:00:10|
Oldest entries (by date) should remain in the table
You want to keep each row where the previous status is different, based on the id or date column.
If your ids are really sequential (as they are in the question), you can do this with a convenient join:
select t.*
from t left outer join
t tprev
on t.id = tprev.id+1
where tprev.id is null or tprev.status <> t.status;
If the ids are not sequential, you can get the previous one using a correlated subquery:
select t.*
from (select t.*,
(select t2.status
from t t2
where t2.user_id = t.user_id and
t2.id < t.id
order by t2.id desc
limit 1
) as prevstatus
from t
) t
where prevstatus is null or prevstatus <> t.status;

Difficulty in resolving union query

I have 2 tables:
S_tbl
====================
id | barcode | qty |
====================
1 | 1234 | 10 |
1 | 111 | 5 |
1 | 1234 | 10 |
K_tbl
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
I run this query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION ALL
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, '0' as NewQty
FROM S_Tbl where S_Tbl.id = 1
and I get this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 0 |
1 | 111 | 5 | 0 |
How to merge same lines that the result will be like this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
EDIT:
i add the line: 1 | 1234 | 10 | to S_Tbl
what i need to change in the query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
that i'll see
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
Right now I see:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
SQL FIDDLE
I am sure this Query will work from MS-ACCES
Use UNION instead of UNION ALL - slower, but cares about the duplicates and removes them. Refer to MSDN doc: http://msdn.microsoft.com/en-us/library/office/bb208962(v=office.12).aspx
By default, no duplicate records are returned when you use a UNION
operation; however, you can include the ALL predicate to ensure that
all records are returned. This also makes the query run faster.
And it is also same in Oracle or MSSQL.