mysql union problems with subtraction - mysql

for example: I have 4 tables:
table 1 : item
item_id name quantity
==========================
1 a 10
2 b 15
table 2 : additional
add_id name quantity item_id
===================================
1 c 5 1
table 3 : item_out (this will subtract item quantity)
item_id quantity
==========================
1 10
2 5
table 4 : additional_out (this will subtract additional quantity)
additional_id quantity
==========================
1 5
My question is: what mysql-query should I give in order to get these result?
item_ id quantity additional_id additinal_quantity
=================================================
1 5 1 0
2 15
because I use mysql query code like:
SELECT item_id, SUM(quantity - IFNULL(number,0)), additional_id, SUM(additional_quantity - IFNULL(additional_number,0))
FROM(
SELECT a.item_id, a.quantity, b.additional_id, b.quantity AS additional_quantity, NULL AS number, NULL AS additional_number
FROM table_1 a JOIN table_2 b ON some condition
UNION
SELECT NULL AS item_id , NULL AS quantity,... a.quantity AS number, b.quantity AS additional_number
FROM table_3 a JOIN table_4 b ON condition
)AS T
and it ends with only 1 row because of SUM in the first selection.

Try this:
SELECT item_ id,
(item.quantity - IFNULL(item_out.quantity,0)) AS quantity,
additional_id,
(IFNULL(a.quantity,0) - IFNULL(ao.quantity,0)) AS additional_quantity
FROM item
LEFT JOIN item_out
ON item.item_id = item_out.item_id
LEFT JOIN additional a
ON item.item_id = a.item_id
LEFT JOIN additional_out ao
ON a.addid = ao.additional_id

Related

How can I retrieve Similar Orders In Mysql?

i need a query that should first look the oldest order which has status 0 (zero). and retrieves all the similar orders of that kind(matches exact total qty, itemSku and number of distinct items ordered).
***OrdersTable***
ID OrderNumber CustomerId Status created_at
1 123456 1 0 2018-01-01
2 234567 1 0 2018-01-02
3 345678 1 0 2018-01-03
4 456789 1 0 2018-01-04
***PurchasedProductsTable***
OrderId itemSku Qty
1 1000001 1
1 1000002 2
2 1000001 3
3 1000001 1
3 1000002 2
4 1000001 3
In the above table the query should first look at the oldest (created_at ASC) order (i.e with Id 1) having status 0 (in order table). and along with that order it should retrieves all the other orders that matches the same itemSku, qty and total distinct items count (in purchasedProducts table).
here order 1 and 3 matches the same itemSKu (1000001 and 1000002) and qty ( 1 and 2) and both have (2) distinct items count respectively so order 1 and 3 should be retrived at first.and when i marked order 1 and 3 as shipped (i.e chang status to 2).
and if i run query again it should retrive similar oders. now order 2 and 4 as order 2 and 4 are similar orders. (have same itemSkus (1000001, Qty (3) and distinct items count (1)).
please help thanks
You have to go trough your tables two times :)
Something like this :
SELECT DISTINCT O2.ID
FROM OrdersTable O1
INNER JOIN PurchasedProductsTable P1 ON O1.ID = P1.OrderId
INNER JOIN PurchasedProductsTable P2 ON P1.itemSku = P2.itemSku
AND P1.Qty = P2.Qty
INNER JOIN OrdersTable O2 ON O2.ID = P2.OrderId
WHERE O1.ID =
(SELECT ID FROM OrdersTable WHERE Status = 0
ORDER BY created_at ASC LIMIT 1)
AND (SELECT COUNT(*) FROM PurchasedProductsTable WHERE OrderId = O1.ID)
= (SELECT COUNT(*) FROM PurchasedProductsTable WHERE OrderId = O2.ID)
ORDER BY O2.ID ASC;
https://www.db-fiddle.com/f/65t9GgSfqMpzNVgnrJp2TR/2
You can get the earliest order via a limit and ordered by the date.
Then you can left join to get that order and any other order that at least has the same items.
Then once you have those order id's from the sub-query result, you can get the order details.
SELECT o.*
FROM
(
SELECT DISTINCT ord2.ID as OrderId
FROM
(
SELECT ID, CustomerId, Status
FROM OrdersTable
WHERE Status = 0
ORDER BY created_at
LIMIT 1
) AS ord1
JOIN PurchasedProductsTable AS pprod1
ON pprod1.OrderId = ord1.ID
LEFT JOIN OrdersTable ord2
ON ord2.CustomerId = ord1.CustomerId
AND ord2.Status = ord1.Status
LEFT JOIN PurchasedProductsTable pprod2
ON pprod2.OrderId = ord2.ID
AND pprod2.itemSku = pprod1.itemSku
AND pprod2.Qty = pprod1.Qty
GROUP BY ord1.CustomerId, ord1.ID, ord2.ID
HAVING COUNT(pprod1.itemSku) = COUNT(pprod2.itemSku)
) q
JOIN OrdersTable AS o ON o.ID = q.OrderId;
Test on RexTester here

Sql query select sum of table1 and sum of table2 and subtract them

Select idn, sum(tblppmp.total_item) as a_total
sum(tblRequest.Quantity) as b_total
sum(a_total- b_total) as itemsleft
FROM PPMP.dbo.tblppmp, ppmp.dbo.tblrequest
Group by idn
i have my problem how to sum individual items from table1 and table2 and the result will be subtracted to get the answer.
like this
table1
id item
1 2
2 3
3 4
table2
id item
1 1
2 2
3 3
the result i want is like this..
table 3
sum(table.item) - sum(table2.item)
table1.id 1 = 2
table2.id 1 = 1
so (2-1) = 1
id item_left
1 1
2 1
3 1
id item
You could caculate sum for each table first and then subtract them.
select idn,
a_total - ISNULL(r_total,0) as itemsleft
FROM
(
select idn, sum(p.total_item) as p_total
from PPMP.dbo.tblppmp p
group by idn
) p
LEFT JOIN
(
select idn, sum(r.Quantity) as r_total
from ppmp.dbo.tblrequest r
group by idn
) r on p.idn = r.idn
You can not use sum(a_total- b_total). You have to use sum(tblppmp.total_item) - sum(tblRequest.Quantity).
Select tblppmp.idn
, tblppmp.total_item as a_total
,tblRequest.Quantity as b_total
,tblppmp.total_item - tblRequest.Quantity as itemsleft
FROM dbo.tblppmp
INNER JOIN
(SELECT
tblrequest.idn
,sum(tblRequest.Quantity) AS Quantity
FROM tblrequest
WHERE tblrequest.dr_year = 2015
GROUP BY tblrequest.idn) tblrequest ON tblppmp.idn = tblrequest.idn

Getting data form 2 tables and summing values of the result

I have 2 tables with information: ID, persona_id, total_amount
The persona ID can repeat dozen of times. So i get all the one persons id total_amount with query:
select d.id as debt_id, p.name as persona, sum(d.total_amount) as total_amount
from debt d
join persons p on d.persona_id = p.id group by p.name
I want to get data from each table in one query and do aritmethic propertys with the total_amount column and return it as 1 tabel.
TABLE 1
id persons_id total_amount
1 2 50
2 3 100
3 2 200
4 5 300
5 1 500
TABLE 2
id persons_id total_amount
1 2 25
2 1 100
3 5 50
4 3 100
5 4 300
As a result i want to get the 2 tables comined with arithmetic operation (-, +, / , * ) of Total amount columns.Basicaly a change to get the ending result total amount in form i want for different cases.
What worked for me based on JohnHC answear was :
select c.id, c.persona_id, c.total_amount - d.total_amount as new_total
from ( select c.id , c.persona_id, sum(c.total_amount) as total_amount from credit c
join persons p on c.persona_id = p.id
group by p.name) c
inner join ( select d.id, d.persona_id, sum(d.total_amount) as total_amount from debt d
join persons p on d.persona_id = p.id
group by p.name) d
on c.persona_id = d.persona_id
group by c.id, c.persona_id
If you want the total, try:
select id, person_id, sum(total_amount)
from
(
select id, person_id, total_amount
from table1
union all
select id, person_id, total_amount
from table2
)
group by id, person_id
If you want to do other things, try:
select t1.id, t1.person_id, t1.total_amount [+ - / *] t2.total_amount as new_total
from table1 t1
inner join table2 t2
on t1.id = t2.person_id
group by t1.id, t1.person_id

Get id value from same table in query

I have this table setup:
orders:
id, order_nr
orders_cart:
id, orders_id,ref_backorder
Some data:
Orders:
id order_nr
1 012345
2 0123456
Orders_cart
id, orders_id, ref_backorder
1 2 1
1 1
the ref_backorder is a reference to another row in the same table.
Expected output:
id, ref_backorder
1 012345
2 null
My query:
SELECT o.id, o.ref_backorder`
FROM orders_cart o
??
LEFT JOIN orders ON o.ref_backorder` = orders.id
??
How can i get the ref_backorder as order_nr?
ref_backorder is an id from a row. In this case row 1, in row 1 we have an orders_id 2. The value of orders_id 2 (0123456) is the value what I want to show in the query.
Can you join the table to itself?
Seems the query could be this
select o.order_nr
from order
inner join orders_cart as c on c.ref_backorder = o.id
where c.orders_id = 2
SELECT A.id, A.orders_id, A.ref_backorder, B.order_nr FROM orders_cart AS A
JOIN orders AS B ON
A.orders_id = B.id

SQL - How to calculate column value and join with another table

As I am not good with MySQL query's so I wish someone help me for creating this kind of sql query.
I having two MySQL tables which is describe bellow:
Table Name: rating
-------------------
property_id user_id area_rate_count safety_rate_count friendly_rate_count walkability_rate_count
4 28 1 1 1 2
5 38 2 3 4 1
5 40 2 2 3 1
6 40 2 3 1 4
10 43 2 2 3 1
Table Name: listing
-------------------
property_id title
4 Sample 1
5 Sample 2
6 Sample 3
10 Sample 4
11 Sample 5
12 Sample 6
Now first I want to sum each column and divide. (area_rate_count, safety_rate_count, friendly_rate_count, walkability_rate_count). For example In property_id:5 having two times so first calculate column sum and divide by 2.
After calculation we will get this output:
Table Name: rating (After Calculation)
--------------------------------------
property_id rate
4 5
5 9 (Divided by 2 because this property_id is two times in table)
6 10
10 8
And Finally I want join this result to my listing table and result looks something like this:
Table Name: listing
-------------------
property_id title rate
4 Sample 1 5
5 Sample 2 9 (Divided by 2 becouse property_id is two times in table)
6 Sample 3 10
10 Sample 4 8
11 Sample 5 0
12 Sample 6 0
Thanks.
I think you want the avg() aggregation function along with a join:
select l.property_id, l.title,
coalesce(avg(area_rate_count + safety_rate_count + friendly_rate_count + walkability_rate_count
), 0) as rate
from listing l left outer join
property_id p
on l.property_id = p.property_id
group by l.property_id, l.title ;
If I understood it right I think you need this:
select l.property_id, l.title, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
See it here on fiddle: http://sqlfiddle.com/#!2/589d6/5
Edit
As OP asked on the comments that he wants all columns from listing here is what he want:
select l.*, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
CREATE TEMPORARY TABLE IF NOT EXISTS
temp_table ( INDEX(col_2) )
ENGINE=MyISAM
AS (
SELECT
property_id,
AVG(area_rate_count) as area_rate_count,
AVG(safety_rate_count) as safety_rate_count,
AVG(friendly_rate_count) as friendly_rate_count,
AVG(walkability_rate_count) as walkability_rate_count
FROM rating
GROUP BY property_id
)
SELECT * FROM listing L
JOIN temp_table T
ON L.property_id = T.property_id
Use the below statement to get distinct property_id with its own rate
select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id
you can then join with the other table to get the final result as below
select * from ( select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id) AS A inner join listing AS B on A.property_id = B.property_id
try this:
select a.prop_id as property_id, l.title, a.allratings / b.numberofreviews as rate
from
(
select property_id as prop_id, SUM(coalesce(area_rate_count,0) + coalesce(safety_rate_count,0) + coalesce(friendly_rate_count,0) + coalesce(walkability_rate_count,0)) as allratings
from rating
group by property_id
) a inner join
(
select property_id, count(distinct user_id) as numberofreviews
from rating
group by property_id
) b on a.property_id = b.property_id
inner join listing l on a.property_id = l.property_id
Try This Query
select ls.property_id,ls.title,inr.rate from listing as ls
left join
(select r.property_id as pid,r.rate/r.cnt as rate from
(select property_id,user_id,(area_rate_count+safefty_rate_count+friendly_rate_count+walkability_rate_count) as rate,count(*) as cnt from rating group by property_id) as r) as inr on inr.pid=ls.property_id