Get SUM another table off all rows in MySQL - mysql

I have database value, for example
table name: a_table
===================================
| userId | userName |
===================================
===================================
| abc | Alice |
| bcd | Rachel |
| efg | Raymond |
===================================
table name: b_transaction
=============================================
| transCode | userId | value |
=============================================
=============================================
| 1 | abc | 100 |
| 2 | abc | -200 |
| 3 | abc | 300 |
=============================================
My goal is, get sum of all data, if user dont have row in table transaction, they must be 0. But when I try this query
SELECT a.userId, a.userName, SUM(b.value)
FROM a_table a
LEFT JOIN b_transaction b ON a.userId = b.userId
The result just return 1 row
================================================
| userId | userName | value |
================================================
================================================
| abc | Alice | 200 |
================================================
How to achieve that?
Thaanks~

You could try grouping the results on the users over the summing of the transactions, like this?
SELECT a.userId, a.userName, SUM(b.value)
FROM a_table a
LEFT JOIN b_transaction b ON a.userId = b.userId
GROUP BY a.userId, a.userName

add group by:
SELECT a.userId, a.userName, IFNULL (SUM(b.value),0)
FROM a_table a
LEFT JOIN b_transaction b ON a.userId = b.userId
GROUP BY a.userId, a.userName
see the sqlfiddle

Using a simple group by statement in your SQL should create the desired result for example:
SELECT a.userId, a.userName, SUM(b.value)
FROM a_table a
LEFT JOIN b_transaction b ON a.userId = b.userId GROUP BY a.userId

You can use IFNULL to check if the result of the sum is null (that is the case if there is no reference for a row from a to b) or not, and then apply a default value :
SELECT a.userId, a.userName, IFNULL(SUM(b.value), 0) AS 'Sum'
FROM a_table a
LEFT JOIN b_transaction b ON a.userId = b.userId
GROUP BY a.userId, a.userName
This outputs :
| userId | userName | Sum |
| ------ | -------- | --- |
| abc | Alice | 200 |
| bcd | Rachel | 0 |
| efg | Raymond | 0 |

Related

Find the number of users who made their first order in each country, each day

I have 2 tables which looked like:
user_dataset
+------+---------------+------------+
|userid| Register_time | Country |
+------+---------------+------------+
| 1 | 03/02/17 | TW |
| 2 | 20/03/17 | SG |
| 3 | 26/03/17 | PH |
| 4 | 05/02/17 | VN |
| 5 | 01/10/17 | ID |
| 6 | 03/09/17 | MY |
| ...| ........ | ... |
+------+---------------+------------+
order_dataset
+--------+--------+------------+--------+------------+
|orderid | userid | itemid | gmv | order_time |
+--------+--------+------------+--------+------------+
|1030132 | 3 | 3366770 | 27,0 | 24/04/17 |
|1030137 | 5 | 6130641 | 69,0 | 02/02/17 |
|1030147 | 1 | 6770063 | 87,0 | 25/04/17 |
|1030153 | 6 | 4193426 | 82,0 | 05/11/17 |
|1030155 | 4 | 8825994 | 29,0 | 03/07/17 |
|1030160 | 2 | 5660916 | 44,0 | 30/01/17 |
|....... | ... | ... | ... | ... |
+--------+--------+------------+--------+------------+
I have been told to Write a SQL statement to find the number of users who made their first order in each country, each day.
I don't understand the question, can someone explain to me what the output looks like? I'm not asking the Queries but if someone willing to write it would be wonderful tho.
Thank you in advance
Join the table user_dataset to a query that returns from order_dataset the date of the 1st order of each userid and aggregate:
select u.country, o.order_time, count(*) counter
from user_dataset u inner join (
select userid, min(order_time) order_time
from order_dataset
group by userid
) o on o.userid = u.userid
group by u.country, o.order_time
If there is a case a user has placed 2 orders at the same day, then instead of count(*) use count(distinct userid).
SELECT a.userid, a.purchase_time,c.country
FROM purchase_tab a
INNER JOIN
(SELECT userid, MIN(purchase_time) As first_occurence
FROM purchase_tab
GROUP BY userid) b
ON a.userid = b.userid AND a.purchase_time = b.first_occurence
INNER JOIN user_tabs c
ON a.userid=c.userid
ORDER BY a.userid
SELECT
country,
order_time,
COUNT(*)
FROM user u
LEFT JOIN(
SELECT
userid,
MIN(order_time) AS min_date
FROM order
GROUP BY userid
) o
ON u.userid = o.userid
LEFT JOIN order ot
ON u.userid = ot.userid
WHERE order_time = min_date
GROUP BY country, order_time
ORDER BY country;

How to LEFT JOIN on a table defined in a table column

Consider the following tables:
User Table
id | name | createdAt |
-----------------------|
1 | John | 2018-02-02 |
Activity Table
id | itemId | itemTable | createdAt |
-------------------------------------|
13 | 1 | User | 2018-02-02 |
14 | 142 | Client | 2018-02-02 |
I want to be able to LEFT JOIN on a table specified in the column:
SELECT b.*
FROM activity AS a
LEFT JOIN *a.tablename* AS b
ON b.id = a.itemid
for MemSQL or MySQL
You cannot do this in a SELECT query. SQL does not operate this way.
If you know there are only two tables, you can express the query like this:
SELECT u.*
FROM USER u
WHERE u.id = (SELECT 1 FROM activity a WHERE a.itemid = u.id)
UNION ALL
SELECT c.*
FROM client c
WHERE c.id = (SELECT 1 FROM activity a WHERE a.itemid = c.id);

Calculate sum on the records while joining two tables with a third table

I have three tables:
mysql> select * from a;
+----+---------+
| ID | Name |
+----+---------+
| 1 | John |
| 2 | Alice |
+----+---------+
mysql> select * from b;
+------+------------+----------+
| UID | date | received |
+------+------------+----------+
| 1 | 2017-10-02 | 5 |
| 1 | 2017-09-30 | 1 |
| 1 | 2017-09-29 | 4 |
+------+------------+----------+
mysql> select * from c;
+------+------------+------+
| UID | date | sent |
+------+------------+------+
| 1 | 2017-09-25 | 7 |
| 1 | 2017-09-30 | 2 |
| 1 | 2017-09-29 | 3 |
+------+------------+------+
If I try to calculate the total number of sent for John, it would be 12. And for received, it would be 10.
But if I try to join all three tables, the result is weird. Here is my query to join three tables:
mysql> select sum(sent), sum(received) from a
-> join c on c.UID = a.ID
-> join b on b.UID = a.ID
-> where a.ID = 1;
+-----------+---------------+
| sum(sent) | sum(received) |
+-----------+---------------+
| 36 | 30 |
+-----------+---------------+
But I need correct numbers (12 and 10, respectively). How can I have correct numbers?
You should join the aggregated result and not the raw tables
select a.uid, t1.received, t2.sent
from a
inner join (
select uid, sum(received) received
from b
group by uid
) t1 on t1.uid = a.id
inner join (
select uid, sum(sent) sent
from c
group by uid
) t2 on t2.uid = a.id
where a.id = 1
You could try below
select bx.id, recieved, sum(c.sent) sent from
(
SELECT a.id, sum(b.received) recieved
from a
INNER JOIN b
ON a.id=b.uid
group by a.id
) bx
INNER JOIN c
ON c.uid=bx.id
group by bx.id, bx.recieved;
>>>Demo<<<
This gets rid of the subquery, but introduces something else you might not want:
( SELECT uid, 'Received' AS direction, SUM(received) AS HowMany
WHERE uid = 1
GROUP BY uid )
UNION ALL
( SELECT uid, 'Sent' AS direction, SUM(sent) AS HowMany
WHERE uid = 1
GROUP BY uid )

How to get SUM in Mysql from another table based on first table

---------------colete--------------------
| id | id_comanda | status | id_lista |
----------------------------------------
| | 21775 | 0 | 3820 |
----------------------------------------
| | 21776 | 0 | 3820 |
----------------------------------------
| | 21777 | 0 | 3820 |
----------------------------------------
-----comenzi--------
| id | taxComanda |
--------------------
|21775| 16.00 |
--------------------
|21776| 00.00 |
--------------------
|21777| 16.00 |
--------------------
I want to get SUM from column taxaComand from table comenzi by making the selection from column id_lista from table colete, so the SUM at the end to be 32.00
This is what i have, but is not good.:
SELECT a.id_comnda AS a_id_comanda, a.id_lista AS a_id_lista,
b.id AS b_id, b.taxaComanda AS b_taxaComanda
(SELECT sum(taxaComanda) FROM comenzi WHERE b.id = a.id_comanda AS totalTaxaComanda)
FROM colete a
INNER JOIN comenzi b ON b.id = a.id_comanda
WHERE a.id_lista = 3820
GROUP BY a.id_comanda
Based on your comment I see no other answer than this :
SELECT SUM(b.taxComanda )
FROM colete a
INNER JOIN comenzi b ON b.id = a.id_comanda
WHERE a.id_lista = 3820
Using subquery and grouping id_lista:
SELECT id_lista, SUM(taxComanda ) as result,
FROM(
SELECT id_comanda , status , id_lista, taxComanda
from colete
left join comenzi on colete.id = comenzi.id_comanda)as sq
group by sq.id_lista

Joining two tables without returning unwanted row

My table structure looks like this:
tbl.users tbl.issues
+--------+-----------+ +---------+------------+-----------+
| userid | real_name | | issueid | assignedid | creatorid |
+--------+-----------+ +---------+------------+-----------+
| 1 | test_1 | | 1 | 1 | 1 |
| 2 | test_2 | | 2 | 1 | 2 |
+--------+-----------+ +---------+------------+-----------+
Basically I want to write a query that will end in a results table looking like this:
(results table)
+---------+------------+---------------+-----------+--------------+
| issueid | assignedid | assigned_name | creatorid | creator_name |
+---------+------------+---------------+-----------+--------------+
| 1 | 1 | test_1 | 1 | test_1 |
| 2 | 1 | test_1 | 2 | test_2 |
+---------+------------+---------------+-----------+--------------+
My SQL looks like this at the moment:
SELECT
`issues`.`issueid`,
`issues`.`creatorid`,
`issues`.`assignedid`,
`users`.`real_name`
FROM `issues`
JOIN `users`
ON ( `users`.`userid` = `issues`.`creatorid` )
OR (`users`.`userid` = `issues`.`assignedid`)
ORDER BY `issueid` ASC
LIMIT 0 , 30
This returns something like this:
(results table)
+---------+------------+-----------+-----------+
| issueid | assignedid | creatorid | real_name |
+---------+------------+-----------+-----------+
| 1 | 1 | 1 | test_1 |
| 2 | 1 | 2 | test_1 |
| 2 | 1 | 2 | test_2 |
+---------+------------+-----------+-----------+
Can anyone help me get to the desired results table?
SELECT
IssueID,
AssignedID,
CreatorID,
AssignedUser.real_name AS AssignedName,
CreatorUser.real_name AS CreatorName
FROM Issues
LEFT JOIN Users AS AssignedUser
ON Issues.AssignedID = AssignedUser.UserID
LEFT JOIN Users AS CreatorUser
ON Issues.CreatorID = CreatorUser.UserID
ORDER BY `issueid` ASC
LIMIT 0, 30
On the general knowledge front, our illustrious site founder wrote a very nice blog article on this subject which I find myself referring to over and over again.
Visual Explanation of SQL Joins
Use this:
SELECT
`issues`.`issueid`,
`issues`.`creatorid`,
`creator`.`real_name`,
`issues`.`assignedid`,
`assigned`.`real_name`
FROM `issues` i
INNER JOIN `users` creator ON ( `creator`.`userid` = `issues`.`creatorid` )
INNER JOIN `users` assigned ON (`assigned`.`userid` = `issues`.`assignedid`)
ORDER BY `issueid` ASC
LIMIT 0 , 30
SELECT DISTINCT (i.issueid, i.creatorid, i.assignedid, u.real_name)
FROM issues i, users u
WHERE u.userid = i.creatorid OR u.userid = assignedid
ORDER BY i.issueid ASC
LIMIT 0 , 30
Not sure if the parenthesis are needed or not.
Does this work?
SELECT
i.issueid,
i.assignedid,
u1.real_name as assigned_name,
i.creatorid,
u2.real_name as creator_name
FROM users u1
INNER JOIN issues i ON u1.userid = i.assignedid
INNER JOIN users u2 ON u2.userid = i.creatorid
ORDER BY i.issueid
SELECT
i.issueid,
i.assignedid,
a.real_name,
i.creatorid,
c.real_name
FROM
issues i
INNER JOIN users c
ON c.userid = i.creatorid
INNER JOIN users a
ON a.userid = i.assignedid
ORDER BY
i.issueid ASC