I am working with an existing database structure (I'm aware the structure might not be perfect, but it is out of my control). I have one table called Users with user id and name among other irrelevant columns.
My problem is with combining users and the table called settlements. The columns in settlements are as following: Case_ID, created_date, approve_date, approving_user_id, control_date, controlling_user_id
How do I interact between the two tables so that my end result shows the names of the ones approving/controlling and not the ID.
I have tried to work with joins but I don't know how to proceed when there are two different users that have approved and controlled.
select
u.user_id, u.agent_name, s.creating_date, s.approving_date,
s.approving_user, s.controlling_date, s.controlling_user
from USERS u
left join SETTLEMENTS s on u.user.id = s.approving_user
I know that I could join them in too two different tables, one called approve and one control but I would prefer to have the end result in the same table.
You want two joins, but you should start with settlements and then bring in the two users tables:
select s.approving_user, s.controlling_date, s.controlling_user,
s.creating_date, s.approving_date,
ua.user_id as approving_user_id, ua.agent_name as approving_agent_name,
uc.user_id as controlling_user_id, uc.agent_name as controlling_agent_name
from settlements s left join
users ua
on ua.user.id = s.approving_user left join
users uc
on uc.user_id = s.controlling_user_id
Related
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.
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.
basically in order to process things quickly I need to be able to access the info from two tables linked by an intermediate reached by a one to many and then a many to many relationship. Specifically I have, the following relevant tables
users[id, ...]
trips[user_id,...]
trip_type[id,trip_id,type_id]
types[id,...]
i.e Users have many trips which have many types which themselves have many trips.
My aim is to get a list of every type id (with repetitions should they occur) associated with a particular user via every trip they have taken.
I'm sure this is trivial to the SQL inclined but I am not one of those individuals and as such am just writing nonsense at this point.
SELECT tt.type_id, u.user_id, tr.id
FROM trip_type tt
INNER JOIN trips tr ON tr.id = tt.trip_id
INNER JOIN types ty ON ty.id = tt.type_id
INNER JOIN users u ON u.id = tr.user_id
WHERE u.user_id = ?
This will return type_ids, user_id and trip ids for a particular user.
select users.id, trip_type.type_id, count(*) from users join trips on trips.user_id = users.id join trip_type on trips.id = trip_type.trip_id group by users.id, trip_type.type_id
This will also give you a count of how many trips of each type a user has taken. This query will not list users who have not taken any trips. If you need those users as well change the word 'join' to 'left join'
It seems to me that there are two scenarios in which to use JOINs:
When data would otherwise be duplicated
When data from one query would otherwise be used in another query
Are these scenarios right? Are there any other scenarios in which to use JOIN?
EDIT: I think I've miscommunicated. I understand how a JOIN works, what I'm not so sure about is when to use one.
JOINS are used to JOIN tables together with related information.
Tipical situations are where you have lets say
A user table where the user has specific security settings. The join would be used such that you can determine which settings the user has.
Users
-UserID
-UserName
UserSecurityRoles
-UserID
-SecurityRoleID
SecurityRoles
-SecurityRoleID
-SecurityRole
SELECT *
FROM Users u INNER JOIN
UserSecurityRoles usr ON u.UserID = usr.UserID INNER JOIN
SecurityRoles sr ON usr.SecurityRoleID = sr.SecurityRoleID
WHERE sr.SecurityRole = 'Admin'
LEFT joins will be used in the cases where you wish to retrieve all the data from the table in the left hand side, and only data from the right that match.
JOINS are used when you start normalizing your table structure. You can crete a table with 100s on columns, where a lot of the data could possibly be NULL, or you can normalize the tables, such that you avoid having too many columns with null values, where you group the appropriate data into table structures.
The answer to this Question has a VERY good link that has graphical display of using JOINs
JOINS are used to return data that is related in a relational database. Data can be related in 3 ways
One to Many relationship (A Person can have many Transactions)
Many to Many relationship (A Doctor can have many Patients, but a Patient can have more than one Doctor)
One to One relationship (One Person can have exactly one Passport number)
JOINS come in various flavours:
AN INNER JOIN will return data from both tables where the keys in each table match
A LEFT JOIN or RIGHT JOIN will return all the rows from one table and matching data from the other table
A CROSS JOIN will return the product of each table
You use joins when you need information from more than one table :)
I'm trying to implement something similar to Ruby on Rails' polymorphic relationships.
I have the following three tables :
Events
Users
Organisations
An event can be owner by either a user or an organisation, so my Events table includes the columns: owner_type and owner_id.
I can easily list all events that belong to either users or organisations through an inner join and where clause, however, is there a way to make the join table conditional based on the value of the owner_type column, allowing all events to be listed together, regardless of owner_type?
I hope that makes sense.
Any advice appreciated.
Thanks.
You can't make the join table conditional, so in this case you would have to join events to both users and organisations and use coalesce to merge the common fields (eg. name) together.
select e.id, coalesce(u.name, o.name) owner_name
from events e
left join users u on e.owner_id = u.id and e.owner_type = 'user'
left join organisations o on e.owner_id = o.id and e.owner_type = 'org'
However, you may consider creating an owners table, which contains both users and organisations, with a structure like (id, type, org_id, name, ...). This would only require a single join, but may complicate other areas of your schema, eg. user membership of an organisation.
An alternative method would be to union the users and organisations tables together and then join once from events.
Owner has columns common to all owner-subtypes.
Person and Organization have columns specific to each one.
How about moving ownership information out of Events into two join tables, EventsUsers and EventsOrganisations (each of which has just two columns, FKs to Events and the apppropriate owning-object table) ? Then you can UNION two queries each of which joins through the join table to the owning-object table.
A bit old, but I think it would be useful, this version performs better in my scenario than multiple joins
select e.id,
case when e.owner_type = 'person' then
(
select p.name from person p
where p.id=e.owner_id
)
else
(
select o.name from organization o
where o.id=e.owner_id
)
end entityName,
e.owner_type
from events e
in postgres you could even build a json of entire related entity