Updating table with sum of selected values from that table itself - mysql

I have a table tmp_addit which looks like this
addition_id allowance_id sal_id amount
--------------------------------------------
1 4 1 300
2 5 1 400
3 6 1 200
4 4 2 300
5 5 2 250
6 6 2 150
I want to update the table such that the amount with allowance_id in (5,6) must be added to allowance_id = 4. Eg: I want to get 900 as amount for (sal_id = 1 and allowance_id = 4).
I tried this code but it's not working
update tmp_addit set amount =(select sum(amount) from tmp_addit
where allowance_id in(5,6)
group by salary_id) where allowance_id=4;
Any help?

With this query:
select salary_id, sum(amount) amount
from tmp_addit
where allowance_id in (5, 6)
group by salary_id
you get the sums that you want to add to the column amount.
Then you need to join this query to the table in an UPDATE statement:
update tmp_addit t
inner join (
select salary_id, sum(amount) amount
from tmp_addit
where allowance_id in (5, 6)
group by salary_id
) g on g.salary_id = t.salary_id
set t.amount = t.amount + g.amount
where t.allowance_id = 4;
See the demo.
Result:
| addition_id | allowance_id | salary_id | amount |
| ----------- | ------------ | --------- | ------ |
| 1 | 4 | 1 | 900 |
| 2 | 5 | 1 | 400 |
| 3 | 6 | 1 | 200 |
| 4 | 4 | 2 | 700 |
| 5 | 5 | 2 | 250 |
| 6 | 6 | 2 | 150 |

I'd use a join on the aggregated query by the sal_id:
UPDATE tmp_addit t
JOIN (SELECT sal_id, SUM(amount) AS sum_amount
FROM tmp_addit
WHERE allowance_id IN (5, 6)) s ON t.sal_id = s.sal_id
SET t.amount = t.amount + s.sum_amount
WHERE allowance_id = 4

Related

How to use Mysql SUM with JOIN

I have the following tables:
purchase_tbl
id | productId | purchaseQuantity
---+-----------+-----------------
1 | 1 | 30
2 | 2 | 30
3 | 1 | 10
4 | 2 | 10
sale_tbl
id | productId | saleQuantity
---+-----------+-------------
1 | 1 | 10
2 | 2 | 10
3 | 1 | 10
4 | 2 | 10
5 | 1 | 10
6 | 2 | 10
I need to get the output as this one:
productId | totalPurchasedQuantity| totalSaleQuantity
----------+-----------------------+------------------
1 | 40 | 30
2 | 40 | 30
I'm using this query and how to get the desired result?
SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM purchase_tbl
JOIN sale_tbl
ON purchase_tbl.productId = sale_tbl.productId
GROUP BY purchase_tbl.productId
Current output
productId | totalPurchaseQuantity | totalSaleQuantity
----------+-----------------------+------------------
1 | 120 | 60
2 | 120 | 60
You better group then in separate query, as table have multiple records for each product, which getting cross product.
SELECT purchase.productId, totalPurchaseQuantity, totalSaleQuantity
FROM
(SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
FROM purchase_tbl
GROUP BY purchase_tbl.productId) purchase
INNER JOIN
(SELECT sale_tbl.productId
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM sale_tbl
GROUP BY sale_tbl.productId
) sale ON sale.productId= purchase.productId;
To obtain your expected result you have to do the aggregation on the individual table before joining them. Your query with be like:
SELECT A.productId, A.totalpurchaseQuantity, B.totalsaleQuantity
FROM
(SELECT productId, SUM(purchaseQuantity)
totalpurchaseQuantity FROM purchase_tbl
GROUP BY productId) A JOIN
(SELECT productId, SUM(saleQuantity)
totalsaleQuantity FROM sale_tbl
GROUP BY productId) B ON
A.productId=B.productId;

Check multiple columns for duplicate and list all records

I have a table with columns ID, Content and Day. I am trying to find all rows that have duplicate Content and Day values and display all rows
SELECT ID,Content, `Day`, Count(*)
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
The current code will return a list of duplicate Content and 'Day' values for instance:
ID|Content|Day
1 | a | 1
2 | a | 1
3 | a | 1
4 | b | 2
5 | b | 2
6 | c | 3
7 | c | 4
Will result in:
ID|Content|Day|Count
1 | a | 1 | 3
4 | b | 2 | 2
But I want to display all the unique IDs as well;
ID|Content|Day
1 | a | 1
2 | a | 1
3 | a | 1
4 | b | 2
5 | b | 2
Just make a Sub-Query
select *
from table
where `day` in
(
SELECT ID
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
) A
Use that query as a subquery to join against the table again:-
SELECT table.ID, table.Content, table.`Day`
FROM table
INNER JOIN
(
SELECT Content, `Day`, Count(*)
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
) sub0
ON sub0.Content = table.Content
AND sub0.`Day` = table.`Day`

Two records limit when the same column

I have column:
id | id_contract | price
I'd like to select all with the limit 2 the cheapest offer from one contract.
I use kochana ORM.
Thanks.
For example
1 | 1 | 100 *
2 | 1 | 500
3 | 1 | 300 *
4 | 1 | 900
5 | 2 | 1000
6 | 2 | 100 *
7 | 2 | 200 *
8 | 3 | 10000 *
This is what I want to select.
You can do this in MySQL with the following query:
select t.*
from table t
where (select count(*)
from table t2
where t2.id_contract = t.id_contract and
t2.price <= t.price
) <= 2;

Addition of the SUM of two independant tables

i have two tables
td_sell
|----------|----------------|------------------|
| id | user_id | price |
|----------------------------------------------|
| 1 | 2 | 10 |
|----------------------------------------------|
| 2 | 1 | 5 |
|----------------------------------------------|
| 3 | 2 | 3 |
|----------------------------------------------|
and td_commsion
|----------|----------------|------------------|
| id | user_id | price |
|----------------------------------------------|
| 1 | 1 | 3 |
|----------------------------------------------|
| 2 | 1 | 5 |
|----------------------------------------------|
| 3 | 2 | 3 |
|----------------------------------------------|
now i want a sql query like this
SELECT (SUM(td_sell.price) + SUM(td_comission.price)) AS his_earning
FROM td_sell, td_comission
WHERE td_sell.user_id='1'
AND td_comission.user_id='1'
but its showing abnormal result
the result should be 13, but its showing 29
This will work:
SELECT (SELECT SUM(s.price) FROM td_sell s WHERE s.user_id = 1)
+
(SELECT SUM(c.price) FROM td_comission c WHERE c.user_id = 1)
DEMO: SqlFiddle
You are getting the sum of the Cartesian join of the two tables.
http://en.wikipedia.org/wiki/Cartesian_product
SELECT sum(price)
FROM (
SELECT * FROM td_sell
UNION ALL
SELECT * FROM td_commission
) a
where a.user_id=1
Here's a SQL Fiddle:
Fiddle
You need to do the sum separately on each table, before combining the results. Here is one way:
select (sell + commission) as his_earning
from (select SUM(td_sell.price) as sell
from td_sell
where td_sell.user_id='1'
) s cross join
(select SUM(td_comission.price) as commission
from td_comission
where td_comission.user_id='1'
) c

MySQL group by with MAX not working as expected?

I have a table:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
3 | 2 | 80
4 | 2 | 100
5 | 1 | 90
6 | 1 | 120
7 | 2 | 120
8 | 1 | 150
9 | 2 | 300
I do a query:
SELECT * FROM TABLE ORDER BY amount DESC group by userid
I'm getting this:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
But I was expecting:
ID | User | Amount
9 | 2 | 300
8 | 1 | 150
What is wrong with my sql?
When grouping you have to use aggregate functions like max() for all columns that are not grouped by
select t.*
from table t
inner join
(
SELECT userid, max(amount) as total
FROM TABLE
group by userid
) x on x.userid = t.userid and x.total = t.amount
ORDER BY t.amount DESC
Another solution.Check SQL Fiddle
Using FIND_IN_SET clause
SELECT
ua.*
FROM user_amount ua
WHERE FIND_IN_SET(ua.amount,(SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)) > 0
ORDER BY amount desc;
Using IN clause
SELECT
ua.*
FROM user_amount ua
WHERE ua.amount IN (SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)
ORDER BY amount desc