collect data from multiple tables with count and sum - php

SELECT sum(amount) as amount , COUNT(userid) as total FROM table1 WHERE userid='1111' union all
SELECT sum(amount) as amount, COUNT(userid) as total FROM table2 WHERE userid='1111' union all
SELECT sum(amount) as amount, COUNT(userid) as total FROM table3 WHERE userid='1111' union all
SELECT sum(amount) as amount, COUNT(userid) as total FROM table4 WHERE userid='1111' union all
SELECT sum(amount) as amount, COUNT(userid) as total FROM table5 WHERE userid='1111'
I found this somewhere but its not working for me .
Proposed solution:
The other option is to get data from all tables separately and then display it .
Question:
I want to get data from multiple tables with single query. amount will be added and userid will be counted from all tables.
Additional Notes:
It should gather all the info about user id = 1111 and save in two varibables.
Userid= 1111 , may not be present in some tables.
Expect out will be like this:
your total : $total | and your amount : $amount
Based on suggestions. here is what i have acheieved so far and how i am trying to display it. it displays nothing without any errors:
If i use single query, then the results are displayed fine.
<?php
$sqltotal=mysql_query("SELECT SUM(data.Amount) as Amount ,SUM(data.total) as total
FROM
(
SELECT COALESCE(sum(amount),0) as amount , COALESCE(COUNT(userid)) as total FROM table1 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table2 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table3 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table4 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table5 WHERE userid='1111'
) as data
");
while($row = mysql_fetch_array($sqltotal))
{
echo "$row[total]";
echo "$row[sum]";
}
//echo "$yourtotal: $row[total]";
?>

If you need the single row for all the tables sum for the column amount then just do the Outer select on UNION. Now as you mentioned in comment may be some of tables may not contain the UserID you need to use the COALESCE to make sure that if null then get the 0 as selected value.
SELECT SUM(COALESCE(data.Amount,0)) as Amount ,SUM(COALESCE(data.total,0)) as total
FROM
(
SELECT COALESCE(sum(amount),0) as amount , COALESCE(COUNT(userid)) as total FROM table1 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table2 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table3 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table4 WHERE userid='1111'
UNION ALL
SELECT COALESCE(sum(amount),0) as amount, COALESCE(COUNT(userid)) as total FROM table5 WHERE userid='1111'
) as data
And if you want to use the join then you need to use the LEFT JOIN and also need to do the SUM separately for each table and then add that to the main total.

SELECT sum(amount) as amount , COUNT(userid) as total FROM table1
Group By userid

Try this:
SELECT sum(table1.amount + table2.amount + table3.amount + table4.amount) as amount, COUNT(table1.userid) + COUNT(table2.userid) + COUNT(table3.userid) + COUNT(table4.userid) as total
FROM table1, table2, table3, table4
WHERE table1.userid='1111' OR table2.userid='1111' OR table3.userid='1111' OR table4.userid='1111'

Related

multiple sum from different tables [duplicate]

I have a union of three tables (t1, t2, t3).
Each rerun exactly the same number of records, first column is id, second amount:
1 10
2 20
3 20
1 30
2 30
3 10
1 20
2 40
3 50
Is there a simple way in SQL to sum it up, i.e. to only get:
1 60
2 80
3 80
select id, sum(amount) from (
select id,amount from table_1 union all
select id,amount from table_2 union all
select id,amount from table_3
) x group by id
SELECT id, SUM(amount) FROM
(
SELECT id, SUM(amount) AS `amount` FROM t1 GROUP BY id
UNION ALL
SELECT id, SUM(amount) AS `amount` FROM t2 GROUP BY id
) `x`
GROUP BY `id`
I groupped each table and unioned because i think it might be faster, but you should try both solutions.
Subquery:
SELECT id, SUM(amount)
FROM ( SELECT * FROM t1
UNION ALL SELECT * FROM t2
UNION ALL SELECT * FROM t3
)
GROUP BY id
Not sure if MySQL uses common table expression but I would do this in postgres:
WITH total AS(
SELECT id,amount AS amount FROM table_1 UNION ALL
SELECT id,amount AS amount FROM table_2 UNION ALL
SELECT id,amount AS amount FROM table_3
)
SELECT id, sum(amount)
FROM total
I think that should do the trick as well.
As it's not very clear from previous answers, remember to give aliases (on MySQL/MariaDb) or you'll get error:
Every derived table must have its own alias
select id, sum(amount) from (
select id,amount from table_1 union all
select id,amount from table_2 union all
select id,amount from table_3
) AS 'aliasWhichIsNeeded'
group by id
Yes!!! Its okay! Thanks!!!!
My code finishing:
SELECT SUM(total)
FROM (
(SELECT 1 as id, SUM(e.valor) AS total FROM entrada AS e)
UNION
(SELECT 1 as id, SUM(d.valor) AS total FROM despesa AS d)
UNION
(SELECT 1 as id, SUM(r.valor) AS total FROM recibo AS r WHERE r.status = 'Pago')
) x group by id
SELECT BANKEMPNAME, workStation, SUM (CALCULATEDAMOUNT) FROM(
SELECT BANKEMPNAME, workStation, SUM(CALCULATEDAMOUNT) AS CALCULATEDAMOUNT,SALARYMONTH
FROM dbo.vw_salaryStatement
WHERE (ITEMCODE LIKE 'A%')
GROUP BY BANKEMPNAME,workStation, SALARYMONTH
union all
SELECT BANKEMPNAME, workStation, SUM(CALCULATEDAMOUNT) AS CALCULATEDAMOUNT,SALARYMONTH
FROM dbo.vw_salaryStatement
WHERE (ITEMCODE NOT LIKE 'A%')
GROUP BY BANKEMPNAME, workStation, SALARYMONTH) as t1
WHERE SALARYMONTH BETWEEN '20220101' AND '20220131'
group by BANKEMPNAME, workStation
order by BANKEMPNAME asc
IN MSSQL You can write this way, But Doing UNION ALL THE Column should be the same for both ways.
I have given this example So that you can understand the process...

How to show total income and monthly income of a grouped column? (MySQL)

I have this table in my database:
I need a query that shows total cost, monthly totalcost, monthly count(roomId), total count(roomId), grouped by room ID.
I tried this query but the result wasn't like what I need
SELECT room_id, type, numberOfBeds,
(SELECT SUM(total_cost)
WHERE date_booked BETWEEN '".$dateFrom."' and '".$dateTo."') as monthlyIncome,
SUM(total_cost) as totalIncome,
COUNT(roomId) as totalReservations,
(SELECT COUNT(roomId)
WHERE date_booked BETWEEN '".$dateFrom."' and '".$dateTo."') as monthlyReservation
FROM indvproj_rooms, indvproj_room_booking_details
WHERE indvproj_rooms.room_id=indvproj_room_booking_details.roomId;
Question is not clear. Whats is difference between monthly and total cost when you are doing SUM??
Please check below query and results if it is same you needed.
SELECT
*
FROM
(
SELECT
roomId,
SUM(total_cost) as monthly_cost,
COUNT(roomId) as monthly_count
FROM
room
group by
roomId,
YEAR(date_booked),
MONTH(date_booked)
)
as r
LEFT JOIN
(
SELECT
roomId as rid,
SUM(total_cost) as total_cost,
COUNT(roomId) as total_count
FROM
room
group by
roomId
)
as t
on r.roomId = t.rid
https://www.db-fiddle.com/f/rEu6RzQTMdFBNS4QxtaAQR/0

Getting min value of two MySQL tables

I've got stuck at joining two tables and fetching the min value of a price.
I have two tables "tb1" and "tb2".
Both includes ean, price and some other columns.
I wan't to get the cheapest price for same ean's.
So I got this left join:
SELECT price,* FROM tb1 as w left join tb2 as e on w.ean=e.ean
But how do I get the cheapest price?
I know MIN() but the problem is, the min price could be in tb1 or tb2...
Hope you could help me :)
Regards :)
You can use the following solution using a sub-select with UNION ALL to merge the tables into one (tbAll):
SELECT ean, MIN(price) FROM (
SELECT ean, price FROM tb1
UNION ALL
SELECT ean, price FROM tb2
) tbAll
GROUP BY ean
... or another solution using the LEFT JOIN:
SELECT w.ean, MIN(LEAST(w.price, e.price))
FROM tb1 AS w LEFT JOIN tb2 AS e ON w.ean = e.ean
GROUP BY w.ean
In case you need additional information, you can use the UNION ALL solution with additional ROW_NUMBER (available since MySQL 8.0):
SELECT t.ean, t.price, t.merchant FROM (
SELECT ean, price, merchant, ROW_NUMBER() OVER (PARTITION BY ean ORDER BY ean, price) AS rn
FROM (
SELECT ean, price, merchant FROM tb1
UNION ALL
SELECT ean, price, merchant FROM tb2
) tbAll
)t WHERE t.rn = 1
... or in case you are using a MySQL version earlier 8.0 you can use the following:
SELECT t.ean, t.price, t.merchant FROM (
SELECT ean, price, merchant, IF(#prev <> ean, #rn:=0, #rn), #prev:=ean, #rn:=#rn+1 AS rn
FROM (
SELECT ean, price, merchant FROM tb1
UNION ALL
SELECT ean, price, merchant FROM tb2
ORDER BY ean, price
) tbAll JOIN (SELECT #rn:=0) init_rn JOIN (SELECT #prev:='') init_prev
)t WHERE t.rn = 1
demo on dbfiddle.uk
Use Case
CASE
WHEN w.price < e.price THEN w.price
ELSE e.price
END AS MINPRICE

update user score from other tables

I have a few tables that each have their own scores for each user. I would like to create a trigger that will add up all those scores for each user and put them in a field called score in the users table.
Tables (They essentially have the same fields with a few different ones) :
Table 1 : {id, user_id, score}
Table 2 : {id, user_id, score}
Table 3 : {id, user_id, score}
users : {id, name, overall_score}
// Overall _score has a value already , so i just want to add the score fields from the other tables to this one.
To achieve this lets first write the select query and get sum of all the scores per user from the 3 given tables and this is how it could be done
select u.*, y.total from users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
Here is the demo http://www.sqlfiddle.com/#!9/6f936/1
Now lets convert the select to an update command and it will be as
update users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
set u.overall_score = coalesce(y.total,0)
here is the demo http://www.sqlfiddle.com/#!9/c6993/1
To select data from multiple tables, you can use SQL JOINS.
See the example below:
SELECT table1.score, table2.score, table3.score
FROM table1 LEFT JOIN table2
ON table1.id=table2.id LEFT JOIN table3 ON table1.id=table3.id
This code will select the score column from table1, table2, and table3 and create one row per user_id, each containing one score-column/ table (in this case 3/ row). It's almost like having a fourth table containing all the scores, and then when you fetch them in PHP, it'd be like fetching an existing row from the database.
EDIT:
To Update the users table in the same query, you could use something like this:
UPDATE `users`,
(
SELECT table1.id as tid, table1.score as t1,
table2.score as t2, table3.score as t3
FROM table1 LEFT JOIN table2 ON table1.id=table2.id
LEFT JOIN table3 ON table1.id=table3.id
) as total
SET total_score = (t1 + t2 + t3) WHERE id = tid

how to pull mysql data from multiple tables with ORDER BY date field?

i am seeking help on a query which shows movement of a stock item for a particular itemid.
Table1 Name: saleitems Fields: itemid, saledate, qty
Table2 Name: purchaseitems Fields: itemid, purchasedate, qty
Table3 Name: stocktransfers Fields: itemid, trfdate, from, to, qty
I want to pull out mysql data from all three tables and sort them based in the date fields. Any help is much appreciated.
The expected output should look like below
select * from saleitems,purchaseitems,stocktransfers
where your condition order by saledate,purchasedate,trfdate
you can use order by clause as given select whichever fields you want based on condition or join as per your logic and use order by
Try this:
(select itemid, "SALES" as type, saledate as dt, qty from salesitems)
union
(select itemid, "PURCHASE" as type, purchasedate as dt, qty from purchaseitems)
union
(select itemid, "STOCKTRANSFER" as type, trfdate as dt, qty from stocktransferitems)
order by dt;
I hope, I got your question right.
Hope this helps
select * from salesitems a
inner join purchaseitems b on a.itemid=b.itemid
inner join stocktransfer c on a.item_id=c.item_id
order by a.saledate,b.purchasedate,c.trfdate
SELECT a.itemid,a.saledate,a.qty,b.purchasedate,b.qty,c.trfdate,c.from,c.to,c.qty
FROM saleitems a INNER JOIN purchaseitems b
ON a.itemid = b.itemid
INNER JOIN stocktransfers c
ON a.itemid = b.itemid
WHERE a.itemid = 10
ORDER BY a.saledate , b.purchasedate , c.trfdate

Categories