There are three table, I mainly would like to query the transaction
User
-----
id
Debit
-----
id
amount
* user_id
create_date
Credit
------
id
amount
* user_id
create_date
So, I would like to get the transaction for particular user that order by the date, like the following
$150 1 2014-06-15 <== debit
$200 1 2014-06-16 <===credit
The problem is how to query? I need to join debit and credit together? Thanks for helping.
Use UNION ALL not JOIN since you want credit and debit rows separate. An extra join to table User if you want to get columns from it.
SELECT d.amount, d.create_date, 'debit' transactionType,
u.user_name
FROM Debit d
INNER JOIN User u
ON d.id = u.user_id
WHERE u.user_id = 1
UNION ALL
SELECT c.amount, c.create_date, 'credit' transactionType,
u.user_name
FROM Credit c
INNER JOIN User u
ON c.id = u.user_id
WHERE u.user_id = 1
ORDER BY create_date
Related
I need to join 2 tables with the 2nd table with JOIN condition that is based on the 3rd JOIN table.
The problem is, I couldn't get the value from 3rd JOIN table while still joining the 2nd table.
View on DB Fiddle
Table A: users
-------
user_id INT PRIMARY
Table B: orders
-------
order_id INT PRIMARY
user_id INT
invoice_id INT
Table C: invoices
-------
invoice_id INT PRIMARY
invoice_status VARCHAR [voided, paid]
This is what I wish to do:
SELECT
A.user_id,
B.order_id,
C.invoice_id,
C.invoice_status
FROM users A
LEFT JOIN orders B
ON (B.user_id = A.user_id
AND C.invoice_status = 'paid')
LEFT JOIN invoices C
ON (C.invoice_id = B.invoice_id)
The 9th line AND C.invoice_status = 'paid') is referring to table C which has not been joined yet, so this query will cause Error in query (1054): Unknown column 'C.invoice_status' in 'on clause'
The reason I cannot have this condition in WHERE clause is because I still want to return all users records regardless of whether they have any order or 'paid' invoice or not. So adding WHERE invoice_status = 'paid' will NOT return users without any order and users with invoice_status = 'voided'.
Also, when a user has two orders linked to two different invoice records, but 1 invoice's invoice_status is 'paid', while the other is 'voided', I only want to return the 'paid' record. There can be many voided invoices, but only 1 'paid' invoice record.
By the way, this is enforced: sql_mode=only_full_group_by, so I can't do GROUP BY user_id without having some kind of aggregated or condition on order_id & invoice_id fields.
SELECT
A.user_id,
B.order_id,
C.invoice_id,
C.invoice_status
FROM users A
LEFT JOIN orders B
ON (B.user_id = A.user_id)
LEFT JOIN invoices C
ON (C.invoice_id = B.invoice_id);
user_id
order_id
invoice_id
invoice_status
1
1
1
voided
1
2
2
paid
2
3
1
voided
3
NULL
NULL
NULL
My desired result:
user_id
order_id
invoice_id
invoice_status
1
2
2
paid
2
3
1
voided
3
NULL
NULL
NULL
Each user_id must only return once, with invoice_status = 'paid' being the preferred row when there are multiple related orders.
Appreciate it if anyone has any idea how to achieve this.
Thanks!
Use ROW_NUMBER() function And number the rows according to user_id and sort according to invoice_status then fetch the first row
SELECT user_id,
order_id,
invoice_id,
invoice_status
FROM
(SELECT
A.user_id,
B.order_id,
C.invoice_id,
C.invoice_status,
ROW_NUMBER() OVER(PARTITION BY A.user_id ORDER BY C.invoice_status) AS num
FROM users A
LEFT JOIN orders B
ON (B.user_id = A.user_id)
LEFT JOIN invoices C
ON (C.invoice_id = B.invoice_id)) t
WHERE num = 1
db<>fiddle
I am able to solve it by using EXISTS thanks to ProGu's comment.
SELECT
A.user_id,
B.order_id,
C.invoice_id,
C.invoice_status
FROM users A
LEFT JOIN orders B
ON B.user_id = A.user_id
AND EXISTS( SELECT
1
FROM
invoices
WHERE
invoices.invoice_id = B.invoice_id
AND invoices.invoice_status = 'paid')
LEFT JOIN invoices C
ON C.invoice_id = B.invoice_id
user_id
order_id
invoice_id
invoice_status
1
2
2
paid
2
NULL
NULL
NULL
3
NULL
NULL
NULL
Thanks!
I have an users table and amount table.
The users table has following columns.
name id
A 1
B 2
C 3
D 4
The amount table has following columns.
userId amount id
1 10 1
1 20 2
1 10 3
2 12 4
I need a sql which sums all the users amount from the amount table
Final output would be
name id totalAmount
A 1 30
B 2 12
C 3 0
D 4 0
I have tried using but does not work. Kindly help
let searchQuery = `SELECT u.id, u.name, (SELECT IFNULL(SUM(amount), 0) from amount WHERE amount.userId = u.id) as totalAmount, FROM users u LEFT JOIN amount amt on u.id = amt.userId WHERE`;
Correct syntax for correlated subquery version
SELECT u.id, u.name, (SELECT coalesce(SUM(a.amount), 0)
FROM amount a
WHERE a.userId = u.id) as totalAmount
FROM users u
You can do it using standard sql aggregation
select
u.name,
u.id,
sum(a.amount) as totalAmount
from users u
left join amount a
on a.userId = u.id
group by u.name, u.id
The left join is just to include those users whitout amounts, which will have a 0 as totalAmount
I have three tables in a database, as follows:
users:
user_id name pbal
1 m1 100
2 m2 200
3 m3 300
4 m4 400
5 m5 500
payouts:
id user_id amount
1 1 100
2 1 200
3 2 300
4 1 400
blocked:
id user_id status
------ -------- ------
1 2 block
2 3 block
Now I want to make a list that excludes users whose user_id is in the blocked table, and that calculates a new total amount based on the pbal from users and the amount from the related rows in payouts:
name total_amount
----- ------------
m1 800
m5 500
m4 400
I have been trying for half an hour, but failed. Can someone help me?
Here's an example:
SELECT u.name, u.user_id, MAX(u.pbal) + SUM(p.amount) AS total_amount
FROM dbo.Payouts p
INNER JOIN dbo.Users u ON u.user_id = p.user_id
LEFT OUTER JOIN dbo.Blocked b ON u.user_id = b.user_id
WHERE b.user_id IS NULL
GROUP BY u.user_id, u.name
ORDER BY MAX(u.pbal) + SUM(p.amount) DESC;
Here is a possible answer:
SELECT u.name, u.user_id,
u.pbal + (
-- this takes amounts from the payouts table
SELECT SUM(p.amount)
FROM dbo.Payouts p
WHERE u.user_id = p.user_id
) AS total
FROM dbo.Users u
WHERE NOT EXISTS (
-- this excludes blocked users
SELECT *
FROM dbo.Blocked b
WHERE u.user_id = b.user_id
)
ORDER BY total;
I prefer subqueries in this case because they make it a bit more explicit
I am trying to join two tables with multiple columns.
users
id | user_id | account_id
balance
id | receiver_account | sender_account | amount
Users table account_id will be in balance table receiver_account field or
sender_account field. So I want to join users account_id with
recevier_account field or sender_account field of balance table.
If I do it this way is it correct,
SELECT *
FROM users
JOIN balance ON balance.receiver_account = users.account_id
OR
balance.sender_account = users.account_id
try this
Select s.id, s.user_id, s.account_id, b.id, b.receiver_account , b.sender_account , b.amount
from users s
inner join balance b on s.account_id = b.account_id
or
b.sender_account = s.account_id
No, do this instead:
SELECT *
FROM balance b LEFT JOIN users receiver ON b.receiver_account = receiver.account_id
LEFT JOIN users sender ON b.sender_account = sender.account_id
I have 3 tables in my mysql DB to query.
Users_rates (fields: id,userid,raterid,rate,eventid) containing all of the rates(rate) that have been assigned to users(userid), participating to specific events(eventid), by other users(raterid)
Events_participants (fields:id,userid,eventid) containing all of the users(userid) participating to each event(eventid)
Users (fields:id,name,lastname)containing all the user relative data
I need to query those three tables to retrieve an event-specific rank for the users' rates.
Ex. John,Erik and Mark participated to 'eventid=31'.
John received 1 rate from Mark, and 2 from Erik.
Mark received 1 rate from Erik.
Nobody has rated Erik though.
I need to retrieve for each user name,lastname and the sum of the rates received for eventid=31
I tried with this:
SELECT events_participants.userid,users.name,users.lastname,
(SELECT SUM(rate)FROM users_rates WHERE users_rates.eventid=31 AND users_rates.userid=events_participants.userid)AS rate
FROM(( events_participants INNER JOIN users ON events_participants.userid=users.id)
LEFT OUTER JOIN users_rates ON events_participants.userid=users_rates.userid )
WHERE events_participants.eventid=31
But I receive:
userid | name | lastname | rate
1 | luca | silvestro | 1
3 | claudio | buricchi | 6
3 | claudio | buricchi | 6
What's the right query?
Thanks
Luca
Try this:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users LEFT JOIN (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp USING (userid)
It might give an error, this might work instead:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users, (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp WHERE users.userid = temp.userid
I don't know if I got the problem right, but maybe something like:
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN users_rates AS ur ON ur.userid = u.id
WHERE ur.eventid = 31
GROUP BY u.id
edit: If you want to receive a list with all users regardless of whether they have any rates at all, you could also join the users_participants table and replace the INNER JOIN of users_rates by a LEFT JOIN. The WHERE clause has to reference events_participants then (not users_rates anymore as it could be NULL):
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN events_participants AS ep ON ep.userid = u.id
LEFT JOIN users_rates AS ur ON ur.userid = u.id AND ur.eventid = ep.eventid
WHERE ep.eventid = 31
GROUP BY u.id