how do use inner join to join two usernames from a second table, once as a sender and then as a receiver; then add records from a third table in SQL? - sql

I have three tables in sql.
transcation_table: id(pk), date_time, sender_wallet(fk), amount_sent, sender_updated_balance, receiver_wallet(fk), amount_received, receiver_updated_balance
wallet_table: id(pk), userid(fk), wallet, currency, balance
user_table: id(pk), uname
all 'id' fields are primary keys
wallet_table.userid is foreign key of user_table.id
transaction_table.sender_wallet is foreign key of wallet_table.id
transaction_table.receiver_wallet is foreign key of wallet_table.id
I am trying to ask the database to give me a new table where any of the records in transaction_table contain a sender_wallet and receiver_wallet for a particular user.
The new returned table should be like:
date_time, sender_uname, amount_sent, sender_updated_balance, receiver_uname, amount_received, receiver_updated_balance
sender_uname and receiver_uname are new columns to be created for the purpose of making a distinction between the sender and receiver username in the newly returned table.
A returned result would be something like:
2023-02-03 09:57:38, marvin381, 40.00, 360.00, hamarni242, 40.00, 440.00
I made some poor attempts at trying to receive the intended result.
I am unable to see how I can pull the uname from the wallet_table effectively twice and join to the new table.
I also am not getting close to creating the new columns 'sender_uname' and 'receiver_uname'.
I have managed to get the inner join to work getting the data but with only one uname, but not the uname twice under 'sender' and 'receiver'.
which is not even working or coming close to the result.

select t.id,
t.date_time,
su.uname as sender_uname,
t.amount_sent,
t.sender_updated_balance,
ru.uname as receiver_uname,
t.amount_received,
t.receiver_updated_balance
from transcation_table t
inner join wallet_table sw on t.sender_wallet = sw.id
inner join wallet_table rw on t.receiver_wallet = rw.id
inner join user_table su on su.id = sw.userid
inner join user_table ru on ru.id = rw.userid
where su.id = x or ru.id = x;
That x would be a parameter (or a constant) written depending on your database which you didn't specify in tags.
PS: You could also join wallet_table and user table once with a CTE but I didn't want to go that route without knowing your database.
Here is a DBFiddle sample

Related

trouble with inner joining 2 tables

I have a database with 2 tables in it one is 'enlistments' and the other one is 'users'. In the enlistments table I have a user_id and in the users table I have a name. I want to get the name of the user which belongs to the id.
I know I need to do this with an inner join like this:
SELECT enlistments.round_id, users.name
FROM enlistments
INNER JOIN users
ON enlistments.user_id=users.name
WHERE enlistments.activity_id = 1;
However I get this error: Warning: #1292 Truncated incorrect DOUBLE value
I did some research and found out it has to do with comparing an int with a string but I don't know how to solve the problem.
This is how my database looks like
join on is the condition you use to join the tables. Here it's enlistments.user_id=users.id.
select e.round_id
,u.name
from enlistments e join users u on u.id = e.user_id
where activity_id = 1
round_id
name
1
test2
Fiddle
To validate and be sure you are pulling back the exact data desired, I usually provide aliases for each column brought back and make sure to bring back the join columns also. It's good practice to label where the columns returned originated.
SELECT
Enlistments.UserID as Enlistments_UserID,
Users.ID as Users_ID,
enlistments.round_id as Enlistments_RoundID,
users.name as Users_Name
FROM enlistments
INNER JOIN users
ON enlistments.user_id=users.id
WHERE enlistments.activity_id = 1;
SELECT EN.round_id, US.name
FROM enlistments EN
INNER JOIN users US
ON US.name= CAST(EN.user_id AS VARCHAR)
WHERE EN.activity_id = 1
What you are needing is the function cast that can convert any kind of data into another, so you'll pass your integer value as the first argument followed by "AS '%DATATYPE'" where %DATATYPE is the kind of data you want to achieve.
In your case:
SELECT CAST(123456 AS VARCHAR)
-- RETURNS : '123456'
Anyway, I’m not sure that you can be able to join these two tables with the join you are using.
For more help please share some data.

Explain what means to join same table twice

I was preparing for exam and I have this exercise that I don't understand
I have table of Clients that have ClientID,
and also I have table of Transactions that have Foreign Key referenced to Clients, SenderID and RecieverID (refering to ClientID)
I need to create view that will show Transactions with Sender name and Reciever Name, and I did it but I don't understand how it works and why
Here is code:
SELECT CS.Name [SenderName], CR.Name [RecieverName]
FROM Transactions T
INNER JOIN Clients CS
ON CS.ClientID = T.SenderID
INNER JOIN Clients CR
ON CR.ClientID = T.RecieverID
Each time you need the name (for sender or recevier ) you need a relation based on the key between the the transaction table and the clients table
you need the name of the sender ( first join with Clients ) and the name for recevier ( second join with Clients )
for avoid confusion between the two (same name) table you need an alias that let you join the specific related tabe .. you use CS and CR as table nale alias
in this way is as you work with two differente table name (or with a logical duplication of the same table)
SELECT CS.Name [SenderName], CR.Name [RecieverName]
FROM Transactions T
INNER JOIN Clients CS ON CS.ClientID = T.SenderID
INNER JOIN Clients CR ON CR.ClientID = T.RecieverID
You can thinks at the table content as a set of data ..so you use two time the same set of data extracting the row mathcing your relation each time.
Each row in the table Transactions contains:
a SenderID which points to a row in the table Clients and
a RecieverID which points to another row in the table Clients.
So you must make one join of Transactions to Clients using SenderID to get the sender's name and another join to Clients using RecieverID to get the reciever's name.

How to select records from database table which has to user id (created_by_user, given_to_user) and replace users id by usernames?

This is task table:
This is user table:
I want to select user tasks.
I would give from backend ("given_to_user) id.
But The thing is I want that SELECTED data would have usernames instead of Id which is (created_by_user and given_to_user).
SELECTED table would look like this.
Example:
How to achieve what I want?
Or maybe I designed poorly my tables that It is difficult to select data I need? :)
task table has to id values that are foreign keys to user table.
I tried many thinks but couldn't get desired result.
You did not design poorly the tables.
In fact this is common practice to store the ids that reference columns in other tables. You just need to learn to implement joins:
SELECT
task.id, task.title, task.information, user.usename AS created_by, user2.usename AS given_to
FROM
(task INNER JOIN user ON task.created_by_user = user.id)
INNER JOIN user AS user2 ON task.created_by_user = user2.id;
Do you just want two joins?
select t.*, uc.username as created_by_username,
ug.username as given_to_username
from task t left join
users uc
on t.created_by_user = uc.id left join
users ug
on t.given_to_user = ug.id;
This uses left join in case one of the user ids is missing.

Query two joins on the same value and table

I'm having trouble doing the following query. The idea is that I have two tables Stores and Users. In Stores I have the columns store_owners and store_last_modified, both values are integer that are related to the id of dbo.Users. How I can display the name that is stored in users related to the two columns. Like that:
select stores.name , users.name as name_store_owner , users.name as name_store_last_modified
from stores
LEFT JOIN users ON stores.store_owners=users.id (related to name_store_owner)
LEFT JOIN users ON stores.store_last_modified=users.id (related to name_store_last_modified)
How do I do that?
Thank you in advance.
You need to give the tables aliases, so you can refer to the same table twice in the from clause. In addition, you need to refer to the right table (users not stores):
select s.name, uo.name as name_store_owner, um.name as name_store_last_modified
from stores s left join
users uo
on s.store_owners = uo.id left join
users um
on s.store_last_modified = um.id
It appears that the condition can be checked without referring the table twice.
select * from
stores s
left join
users u on u.id = s.store_owners
and u.id = s.store_last_modified
From your question it appears that user id (id) should match with both the columns in the stores table for a single row.

Populating sql table from multiple sources

Here is my setup:
old tables
Location [ID, Country, Region]
IpAddress [ID, IP]
Session [ID, IpAddressId, LocationId]
new tables
Country[ID, Country]
Region[ID, Region]
IpAddress[ID, IP]
Profile[ID, IpAddressId, CountryId, RegionId]
Session[ID, ProfileId]
I have already deconstructed the Location table. Now I'm getting lost in the weeds on how to insert to the Profile table, and associate it with the session. To note, the old Location table still exists and I don't plan on dropping it till the Profile table is completely updated. Any help would be appreciated.
To create the Profile table you need to build a query that connects the relations of each table, but you can't use your id columns to link the new tables to the old, since those are no longer relational. This should work for you:
--INSERT INTO Profile (IpAddressId, CountryId, RegionId)
SELECT S.IpAddressId, C.ID, R.ID
FROM Session S --Old Session table
INNER JOIN Location L on S.LocationId = L.ID
INNER JOIN Country C on C.Country = L.Country
INNER JOIN Region R on R.Region = L.Region
Note: this is assuming that the IpAddress table will remain unchanged, and use the same IpAddressId.
That said, I think your issue is how to link this to the new Session table. To answer that, we would need to know what the new Session table will do.. but in general, you would go about populating it in the same way as the above query. Join it to the corresponding tables on the matching data in order to get the new id relations.