MySQL Query for subtracting values from 2 tables - mysql

Hello I have this tables
Table A
ID Name Price QTY
1 name1 1000 10
2 name2 1200 5
Table B
ID Name Price QTY
1 name1 1000 2
I want to achieve
Table C
ID Name Price QTY
1 name1 1000 8
2 name2 1200 5
With my query SELECT DISTINCT ta.name, ta.price,(ta.quantity - tb.quantity) AS quantity, FROM TableA AS ta INNER JOIN TableB AS tb ON ta.id = tb.id
What I get is this
Table C
ID Name Price QTY
1 name1 1000 8
2 name2 1200 3
I sorry I really cant think of a way how to achieve what I want. Thanks for your help.

Your query actually gets you one line instead of two:
-- result set
# name, price, quantity
name1, 1000, 8
Based on your expected output,we can use:
SELECT ta.ID, ta.name, ta.price, ifnull((ta.QTY - tb.QTY),ta.QTY) AS quantity
FROM TableA AS ta
LEFT JOIN TableB AS tb
ON ta.name = tb.name and ta.price=tb.price;
-- result set:
# ID, name, price, quantity
1, name1, 1000, 8
2, name2, 1200, 5
This is the last updated answer I can give you for you updated request.Please consider firing a new question if it does not fulfill.
-- Supposing your latest tables have the following data.
insert TableA values
(1 , 'name1' , 1000 , 10)
,(2 , 'name2' , 1200 , 5);
insert TableB values
(1 , 'name1' , 1000 , 2),
(2 , 'name2', 1000 , 3)
;
-- You probably want this:
SELECT ta.ID, ta.name, ta.price, ifnull((ta.QTY - tb.QTY),ta.QTY) AS quantity
FROM TableA AS ta
LEFT JOIN TableB AS tb
ON ta.name = tb.name and ta.price=tb.price
union
SELECT Id , name , price , QTY
from TableB t
where not exists (select * from TableA where t.name=name and t.price=price)
;
-- result set:
# ID, name, price, quantity
1, name1, 1000, 8
2, name2, 1200, 5
2, name2, 1000, 3

Related

count from multiple tables in MySQL/oracle

there are 4 tables:A,B,C,D
there is an id:4(input)
the query should print the number of times the id is present in the tables
EX:
in table A id:4 occurs 5 times
in table B id:4 occurs 7 times
in table C id:4 occurs 3 times
in table D id:4 occurs 1 times
output:
Table name No of occurence
A 5
B 7
C 3
D 1
you can try something like that:
select 'A', count(*) from a where id = 4
union all
select 'B', count(*) from b where id = 4
union all
select 'C', count(*) from c where id = 4
union all
select 'D', count(*) from d where id = 4
select id as Name,count(id) as occurence from tableA where id = 4 group by id
union all
select id as Name,count(id) as occurence from tableB where id = 4 group by id
union all
select id as Name,count(id) as occurence from tableC where id = 4 group by id
union all
select id as Name,count(id) as occurence from tableD where id = 4 group by id
Do the union all
select 'A' as Name, count(*) as occurence from tablea where id = ?
union all
select 'B' as Name, count(*) as occurence from tableb where id = ?
union all
select 'C' as Name, count(*) as occurence from tablec where id = ?
union all
select 'D' as Name, count(*) as occurence from tabled where id = ?

JOIN, GROUP BY, SUM Issue Mysql

Assuming I have this table
tableA
ID value
1 5
1 5
3 10
2 4
2 2
1 2
tableB
ID Name
1 apple
2 carrot
3 banana
If the expected max value of apple is 10, carrot is 5, and banana is 15 the output table would be
table output
ID Name value
1 apple 12
2 carrot 6
what SQL statement I need to solve this?
what I have done so far:
SELECT a,ID, b.name , sum(a.valueSUM) AS value FROM tableA a
INNER JOIN tableB b
ON a.id = b.id
GROUP BY id
what options i need on the WHERE clause to pull this off?
The inner subquery groups them normally and then the main query is what deals with limiting the results.
SELECT * FROM
(select
b.id,
b.name as name,
SUM(a.value) as the_sum
from tableA a inner join tableB b
on a.Id = b.id
group by b.name, b.id
) y
where (name = 'apple' and the_sum >= 10) OR
(name = 'banana' and the_sum >= 15) OR
(name = 'carrot' and the_sum >= 5)
It seems your sample data has changed, please try this. I thought the ID doesnt have to follow tableA/tableB's id and the id is auto-generated as per the results.
Would be nice if you have another table that sets the threshold per name
Assuming threshold can be specified in tableB (makes sense):
SELECT a.ID, b.name, sum(a.value) AS value
FROM tableA a
INNER JOIN tableB b
ON a.id = b.id
GROUP BY a.ID, b.name, b.Threshold
HAVING sum(a.value) > b.Threshold;
Demo: http://rextester.com/ICOQF10295
SELECT TableB.id, TableB.Name, MAX(TableA.value) AS Value
FROM TableA INNER JOIN TableB ON
TableA.id = TableB.id
GROUP BY TableB.id, TableB.Name
Instead of SUM, use MAX aggregate function
This works in SQL Server
--Existing tables
create table #tableA (ID int, value int)
create table #tableB (ID int, Name varchar(30))
insert into #tableA
select 1 , 5 union all
select 1 , 5 union all
select 3 , 10 union all
select 2 , 4 union all
select 2 , 2 union all
select 1 , 2
insert into #tableB
select 1 , 'apple' union all
select 2 , 'carrot' union all
select 3 , 'banana'
--Create new temporary table #tableC
create table #tableC (ID int, MAXvalue int)
insert into #tableC
select 1 , 10 union all
select 2 , 5 union all
select 3 , 15
select c.ID,b.Name, a.value from #tableC c
inner join #tableB b on b.ID = c.ID
inner join (
select ID,SUM(value) as value from #tableA
group by ID
) a on a.ID = c.ID
where a.value >= c.MAXvalue
drop table #tableA
drop table #tableB
drop table #tableC

SQL query returns wrong result set

I have this table:
columns:
Id product_id name status update_date
1 1 prod1 bought 2016-04-20 10:10:10
2 1 prod1 sold 2016-04-22 12:25:00
3 1 prod1 sold 2016-06-03 09:42:15
I wanna execute this query:
select id,name,status,max(update_date) from product group by name,status;
I get:
1 prod1 bought 2016-04-20 10:10:10
2 prod1 sold 2016-06-03 09:42:15
For the second row in the result set, I have to get:
3 prod1 sold 2016-06-03 09:42:15
and not: 2 prod1 sold 2016-06-03 09:42:15 !
Try this;)
select id,name,status,update_date from product
where (name, status, update_date) in (
select name,status,max(update_date) from product
group by name,status
)
Or
select t1.id, t1.name, t1.status, t1.update_date
from product t1
inner join (
select name,status,max(update_date) as update_date from product
group by name,status
) t2 on t1.name = t2.name and t1.status = t2.status and t1.update_date = t2.update_date
Simple Query, try this
select product_id,name,status,MAX(update_date) as date
from product group by product_id,name,status
select distinct A.id, A.name, A.status, A.update_date
from product A,
(select `name`,status,max(update_date) update_date
from product
group by `name`, status) B
where A.name=B.name and A.status=b.status and a.update_date=b.update_date
Explanations: the distinct is used in case you have 2 exact update_dates
SQLFiddle : http://www.sqlfiddle.com/#!9/b8218/2
I have tried the query and it is working.
CREATE TABLE ##product(
Id INT,
product_id INT,
name NVARCHAR(100),
status NVARCHAR(100),
update_date DATETIME
);
INSERT INTO ##product
VALUES
(1, 1, 'prod1', 'bought', '2016-04-20 10:10:10'),
( 2, 1, 'prod1', 'sold', '2016-04-22 12:25:00'),
(3, 1, 'prod1' , 'sold', '2016-06-03 09:42:15')
SELECT id, name, status, update_date FROM ##product WHERE update_date IN
(
SELECT MAX(update_date) FROM ##product GROUP BY name, status
)
DROP TABLE ##product

mysql union problems with subtraction

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

UPDATE FROM SELECT with foreign key on parent with one query

How to update (change from first select table value second) second_table.first_table_id if first_table.email match in both select.
If it even possible. With one query!
----------------------------------------- UPDATE -----------------------------------------
EXAMPLE:
I need to update foreign key of second table if email field match in first table. I need to compare two query results with different parent_id (parents are in in same table with children)
table_1
-------------------------
| id | parent_id | email |
-------------------------
1 NULL NULL
2 NULL NULL
3 1 joe#m.ru
4 2 bob#f.ly
5 1 bob#f.ly
6 2 kira#.us
table_2
----------------
| id | first_id |
----------------
1 3
2 4
3 5
4 6
I have two parents with ids 1 and 2 and some children (ids: 3,4,5,6).
Also, keep in mind: 1 - old, 2 - new
Task: change foreign key in second table if children email with parent_id = 1 and chilren email with parent_id = 2 match (are the same).
In our example in second table row with id = 3 its foreign key field - first_id has to change from 5 to 4.
Following might get you started
UPDATE Table_2 t2u
SET first_id = (
SELECT t2.first_id
FROM Table_2 t2
INNER JOIN Table_1 t1 ON t1.id = t2.first_id
INNER JOIN (
SELECT parent_id = MAX(parent_id), email
FROM Table_1
GROUP BY
email
) t1p ON t1p.email = t1.email
INNER JOIN Table_1 t1i ON t1i.email = t1p.email
AND t1i.parent_id = t1p.parent_id
WHERE t2u.first_id <> t1i.id)
Test script (SQL Server)
;WITH Table_1 (id, parent_id, email) AS (
SELECT 1, NULL, NULL
UNION ALL SELECT 2, NULL, NULL
UNION ALL SELECT 3, 1, 'joe#m.ru'
UNION ALL SELECT 4, 2, 'bob#f.ly'
UNION ALL SELECT 5, 1, 'bob#f.ly'
UNION ALL SELECT 6, 2, 'kira#.us'
)
, Table_2 (id, first_id) AS (
SELECT 1, 3
UNION ALL SELECT 2, 4
UNION ALL SELECT 3, 5
UNION ALL SELECT 4, 6
)
SELECT t2.*, t1i.id as [update with]
FROM Table_2 t2
INNER JOIN Table_1 t1 ON t1.id = t2.first_id
INNER JOIN (
SELECT parent_id = MAX(parent_id), email
FROM Table_1
GROUP BY
email
) t1p ON t1p.email = t1.email
INNER JOIN Table_1 t1i ON t1i.email = t1p.email
AND t1i.parent_id = t1p.parent_id
WHERE t2.first_id <> t1i.id
Output
id first_id update with
----------- ----------- -----------
3 5 4