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
Related
I have 2 tables table name is users and projects.the structure of table is:
user table
id | name | role
1 | samjad | user
2 | saneer | constructor
projects table
id | name | user_id | constructor_id |
1 | school | 1 | 2 |
How can i get all details from both table in a single row based on project table id.
i want to select
projectname username, constroctorname, user_id, constroctor_id
in a single row
You can join the user table twice - Once as users and then as constructors.
select p.name as projectname,
u.name as username,
c.name as contructorname,
p.user_id,
p.contructor_id
from projects p
left join user u on p.user_id = u.id
left join user c on p.contructor_id = c.id
where u.role = 'user' -- check if the said user has role "user"
and c.role = 'constructor'; -- check if the said constructor has role "constructor"
Do the fact you have two relation between project table and user (one for user and one for constroctor) You can use user joined for two time
select p.name, u1.username, u2.username, p.user_id, p.constroctor_id
from projects as p
inner join user as u1 on p.user_id = u1.id
inner join user as u2 on p.constroctor_id = u2.id
You can use concat() function:
SELECT CONCAT(field1, field2, field3);
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_concat
or CONCAT_WS(separator,str1,str2,...)
Assuming there is a table called Constructor with columns name and constructor_id your query would be
select
p.name as projectname,
u.name as username,
c.name as constructorname,
u.id as userid,
c.id as constructorid
from
projects p
inner join user u on p.user_id=u.id
inner join constructor c on p.constructor_id=c.id
Use a join. You probably want an INNER JOIN:
SELECT * -- actually include only the fields you need
FROM Projects p
INNER JOIN Users u ON u.id = p.user_id
INNER JOIN Users uc ON uc.id = p.constructor_id
You'll want to join the tables on their keys. In this case something like the below:
select p.name as projectname
, u.name as username
, if(u.role='constructor',u.name,null) as constructorname
, p.user_id, p.constructor_id
from users u
join projects p
on p.user_id = u.id;
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
I have the following query which works (without the "WHERE stats.dt" part). I get all users with their data.
My problem is that this query of course results in rows ONLY with users that have stats.dt > $timestampnow-$maxdays_data). But I need ALL users but their values of SUM(upload) or SUM(download) need only to be fetched when stats.dt is larger than tstamp-maxdays. The other rows with values of upload and download where stats.dt is smaller than what I need, can be ignored.
An example would be that the user with nodeid 2 would not be selected because his dt is too small. I do want the user to be selected but just not with data or upload values (they can be 0).
The stats table looks like this
nodeid | dt | upload | download
----------------------------------------
1 | 1381699533 | 345345 | 42324234
1 | 1382899152 | 7575 | 574234
1 | 1380699533 | 764534 | 7235232
2 | 1372899152 | 71455 | 124123
I don't know where to start looking how to solve this so maybe somebody out there can point me in the right direction. Thanks!
SELECT b.id, b.lastname, b.name, c.balance, a.maxdebt, b.warndata, b.warndownload, b.warnupload, b.warndebt, b.cutoffdata, b.cutoffdownload, b.cutoffupload, b.cutoffdebt, b.data, b.download, b.upload, b.warning, b.access, b.cutoffstop
FROM (
SELECT customers.id AS id, SUM(tariffs.value) AS maxdebt
FROM tariffs
LEFT JOIN assignments ON tariffs.id = assignments.tariffid
RIGHT JOIN customers ON assignments.customerid = customers.id
GROUP BY id
) a
JOIN (
SELECT customers.id AS id, UPPER(lastname) AS lastname, customers.name AS name, SUM(stats.upload+stats.download) AS data, SUM(stats.download) AS download, SUM(stats.upload) AS upload, customers.cutoffstop, warndata, warndownload, warnupload, warndebt, cutoffdata, cutoffdownload, cutoffupload, cutoffdebt, nodes.warning, nodes.access
FROM customers
LEFT JOIN nodes ON customers.id = nodes.ownerid
LEFT JOIN stats ON nodes.id = stats.nodeid
LEFT JOIN customerwarnings ON customers.id = customerwarnings.id
WHERE stats.dt > ($timestampnow-$maxdays_data)
GROUP BY id
) b ON a.id = b.id
JOIN (
SELECT customerid, SUM(cash.value) AS balance
FROM cash
GROUP BY customerid
) c ON b.id = c.customerid
Here's a brute force way of doing it. It can almost certainly be simplified, but without knowing more about the table and foreign key structures it's hard to be sure.
What I've done is replace sum(stats.download) with sum(case when stats.dt > ($timestampnow-$maxdays_data) then s.download end) and similarly for upload. I've also changed the join on b to be an outer join:
Select
b.id,
b.lastname,
b.name,
c.balance,
a.maxdebt,
b.warndata,
b.warndownload,
b.warnupload,
b.warndebt,
b.cutoffdata,
b.cutoffdownload,
b.cutoffupload,
b.cutoffdebt,
b.data,
b.download,
b.upload,
b.warning,
b.access,
b.cutoffstop
From (
Select
c.id,
sum(t.value) as maxdebt
From
tariffs t
left join
assignments a
on t.id = a.tariffid
right join
customers
on a.customerid = c.id
Group by
c.id
) a left outer join (
Select
c.id,
upper(lastname) as lastname,
c.name,
sum(s.upload + s.download) as data,
sum(case when stats.dt > ($timestampnow-$maxdays_data) then s.download end) as download,
sum(case when stats.dt > ($timestampnow-$maxdays_data) then s.upload end) as upload,
c.cutoffstop,
warndata,
warndownload,
warnupload,
warndebt,
cutoffdata,
cutoffdownload,
cutoffupload,
cutoffdebt,
n.warning,
n.access
From
customers c
left join
nodes n
on c.id = n.ownerid
left join
stats s
on n.id = s.nodeid
left join
customerwarnings w
on c.id = w.id
Group By
c.id
) b
On a.id = b.id
inner join (
Select
customerid,
sum(cash.value) as balance
From
cash
Group By
customerid
) c
on a.id = c.customerid
I have a renting schema in my database.
It has 3 tables, user, rentingTrack and lock.
user has as unique element RFIDCode.
in rentingTrack I may have the user(he or she rented at least once) or not (he/she never rented). If the user rented I need the returnLock for the last rent, as rentingID is autoincremented, it is max(rentingID).
With lock table I got the parkingID, the data I need.
The problem is how to get the parkingID, I have half query:
SELECT u.userID, l.parkingID
FROM locks l, user u
LEFT JOIN (SELECT r1.* FROM rentingTrack r1 INNER JOIN
(SELECT userID, MAX(rentingID) maxRentingID FROM rentingTrack GROUP BY userID) r2
on r1.rentingID = r2.maxRentingID) r on u.userID = r.userID
WHERE u.userCodeRFID= 3166681355
What i need is, if userID isn't in the rentingTrack table I got:
userID | parkingID
----------+-----------
34 | NULL
And if userID is in the rentingTrack
userID | parkingID
----------+-----------
34 | 5
how can I complete the query to get parkingID?
Try This. (Need some sample data for duplicates)
select distinct u.userID,l.parkingID
from users
left join rentingTrack r on u.userID=r.userID
left join locks l on r.returnLock=l.lockid
SELECT u.userID, l.parkingID
FROM user u
LEFT JOIN (SELECT r1.userID, r1.returnLock
FROM rentingTrack r1
INNER JOIN
(SELECT userID, MAX(rentingID) maxRentingID
FROM rentingTrack
GROUP BY userID) r2
ON r1.rentingID = r2.maxRentingID) r on u.userID = r.userID
LEFT JOIN locks l ON r.returnLock = l.lockID
WHERE u.userCodeRFID= 3166681355
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