I have two tables.
common_products
id
product
owner_uid
backup_uid
manager_uid
ss_users
userID
firstName
lastName
email
I want to get a name/email list of all the owners, backups and managers.
I am using the query below, but was wondering if there was a more efficient way to go about querying the tables.
WORKING QUERY:
SELECT DISTINCT email,
( firstName + ' ' + lastName ) AS userFull,
lastName
FROM common_products cp
LEFT OUTER JOIN ss_users u
ON u.userID = cp.owner_uid
UNION
SELECT DISTINCT email,
( firstName + ' ' + lastName ) AS userFull,
lastName
FROM common_products cp
LEFT OUTER JOIN ss_users u
ON u.userID = cp.backup_uid
UNION
SELECT DISTINCT email,
( firstName + ' ' + lastName ) AS userFull,
lastName
FROM common_products cp
LEFT OUTER JOIN ss_users u
ON u.userID = cp.manager_uid
Is there a more optimized way to query the database?
I suspect that this version might be faster:
select u.email, (u.firstName+ ' '+u.lastName) AS userFull, u.lastName
from ss_users u
where exists (select 1 from common_products cp where u.userID = cp.owner_uid) or
exists (select 1 from common_products cp where u.userID = cp.backup_uid) or
exists (select 1 from common_products cp where u.userID = cp.manager_uid);
Then for best performance add three indexes: common_products(owner_uid), common_products(backup_uid), and common_products(manager_uid).
This will eliminate the duplicate elimination (because you are using union) and the exists should be at least as fast as the joins.
I'm going to simplify it, but the JOIN is the important part. I'll leave it to you to tweak the SELECT part.
SELECT DISTINCT owner.email AS owner_email, backup.email AS back_email, manager.email AS man_email
FROM common_product cp LEFT JOIN ss_users owner on owner.userID = cp.owner_uid
LEFT JOIN ss_users backup on backup.userID = cp.backup_uid
LEFT JOIN ss_users manager on manager.userID = cp.manager_uid
Ensure there are indexes on common_products's owner_uid, backup_uid, and manager_uid fields as well as ss_users's userID field and you could improve performance a bit further by including the columns needed on the index.
SELECT DISTINCT
user_owner.email [OwnerEmail],user_owner.firstName + ' ' + user_owner.lastName [OwnerUserFull], user_owner.lastName [OwnerLastName],
user_backup.email [BackupEmail],user_backup.firstName + ' ' + user_backup.lastName [BackupUserFull], user_backup.lastName [BackupLastName],
user_manager.email [ManagerEmail],user_manager.firstName + ' ' + user_manager.lastName [ManagerUserFull], user_manager.lastName [ManagerLastName]
FROM common_products cp
LEFT OUTER JOIN ss_users user_owner ON user_owner.userID = cp.owner_uid
LEFT OUTER JOIN ss_users user_backup ON user_backup.userID = cp.backup_uid
LEFT OUTER JOIN ss_users user_manager ON user_manager.userID = cp.manager_uid
It's been a while since I've practised by SQL fu, but I think this should work:
SELECT DISTINCT email,
(firstName+ ' '+lastName) AS userFull,
lastName
FROM common_products cp
INNER JOIN ss_users u
ON (u.userID = cp.owner_uid OR u.userID = cp.backup_uid OR u.userID = cp.manager_uid)
Related
I am trying to perform this query :
List<string> info = db.Database.SqlQuery<string>("
SELECT u.Name, a.LName
FROM dbo.Table1 u
INNER JOIN dbo.Table2 a ON a.Table1id = u.id
WHERE u.Name = '" + name + "'").ToList();
When I try and do that query I get this error:
The data reader has more than one field. Multiple fields are not valid
for EDM primitive or enumeration types.
When I just tried to select the Name without the inner join it worked fine so how do I fix that so that I can perform my inner join without errors?
Thanks!
What #xdd said worked well
List<string> info = db.Database.SqlQuery<string>("
SELECT u.Name + a.LName
FROM dbo.Table1 u
INNER JOIN dbo.Table2 a ON a.Table1id = u.id
WHERE u.Name = '" + name + "'").ToList();
Fixed that
I had three tables: sarcuser, sarcusercommittee, sarcallcourse. I need to build a query that brings all the users that don't have a committee (they don't have a record in sarcusercommittee). Here is my current query:
SELECT u.firstname + ' ' + u.lastname AS name, u.dateofbirth, u.gender, LEFT(u.note, 200) AS note, c.name AS coursename
FROM sarcuser AS u INNER JOIN
sarcusercommittee AS uc ON u.id = uc.user_id INNER JOIN
sarcallcourse AS c ON c.id = u.courseid
WHERE ((SELECT COUNT(id) AS Expr1
FROM sarcusercommittee
WHERE (user_id = u.id)) = 0)
ORDER BY name DESC
I guess the problem is in (ON condistion) but don't get it ... any help ?
NOTE : I use visual studio 2010
SELECT u.firstname + ' ' + u.lastname AS name, u.dateofbirth, u.gender, LEFT(u.note, 200) AS note, c.name AS coursename
FROM sarcuser AS u
INNER JOIN sarcallcourse AS c
ON c.id = u.courseid
WHERE u.id NOT IN (
SELECT uc.user_id
FROM sarcusercommittee AS uc
)
ORDER BY name DESC
Firstly you shouldn't inner join onto sarcusercommittee if you dont want rows from it. Seconly I would filter to the users that are not in sarcusercommittee using NOT IN.
I have two tables one is Friends table and other table is user profile table (all user related information e.g. firstname, lastname etc) both has relation among them
Friend table (It has two entries for every user for e.g. the first two rows)
Now i want to display names of users from above table which will look like below
so in the output i want to remove duplicates which is not working for me
my query
select distinct u.FirstName + ' ' + u.LastName As UserName,
(select distinct firstname + ' ' + lastname from UserProfiles where id = uw.friendid) as FriendName
from UserFriends as uw left join userprofiles as u
on u.id = uw.userid
You need to join UserProfiles twice on UserFriends since there are two columns are dependent on it.
SELECT a.ID,
f.FirstName + ' ' + f.LastName FriendName,
u.FirstName + ' ' + u.LastName UserName
FROM UserFriends a
INNER JOIN UserProfiles f
ON a.FriendID = f.ID
INNER JOIN UserProfiles u
ON a.UserID = u.ID
INNER JOIN UserFriends dup
ON a.FriendID = dup.UserID
AND dup.FriendID = a.UserID
AND a.ID > dup.ID
SQLFiddle Demo
I would suggest that you have to use CTE to eliminate the duplicates from the beggining(that can be done by self joining the table). I have managed to reproduce your scenario, so if you adjust the query a bit, you will be able to obtain the desired result
with cte as
(select
t1.id as a_id
,t1.friendID as a_friendID
,t1.userID as a_userID
,t2.id as b_id
,t2.friendID as b_friendID
,t2.userID as b_userID
from #temp t1
left join #user t2 on t1.id+1=t2.id
),
cte2 as
select
a_id
,a_userID
,a_friendID
from cte t1
where a_friendID = (select b_friendID from cte t2 where t2.b_id= t1.b_id-1)
)
select firstname+ ' '+lastname as FriendName
,firstname+ ' '+lastname as UserName
from cte2 uw
left join UserProfiles u on uw.a_userID=u.ID and uw.a_friendID=u.id
I've got the following SQL Statement:
select * from Leaves inner join LeaveDetails on Leaves.LeaveId= LeaveDetails.LeaveId
inner join Employee on Leaves.EmployeeCode = Employee.EmployeeCode
inner join LeaveType on Leaves.LeaveTypeId= LeaveType.LeaveTypeId
inner join LeaveStatus on Leaves.StatusId = LeaveStatus.StatusId
inner join Employee_organizationaldetails on Employee_organizationaldetails.EmployeeCode=Employee.EmployeeCode
where Leaves.LeaveId = 7295
Employee_organizationdetails contains another column called reporting officer which is a foreign key to the same Employee table. Now I need to get the name of the Employee.
How can I write the above query so that I can get the name of the reporting officer as another column without fetching executing the query
select (FirstName + ' ' + LastName) as name from Employee where EmployeeCode = ReportingTo
Here ReportingTo is the employee code. I need to join them vertically. Something similar to Union operator
You want to join back to another "copy" of the Employee table:
select *, (ro.FirstName + ' ' + LastName) as ReportingName
from Leaves inner join LeaveDetails on Leaves.LeaveId= LeaveDetails.LeaveId
inner join Employee on Leaves.EmployeeCode = Employee.EmployeeCode
inner join LeaveType on Leaves.LeaveTypeId= LeaveType.LeaveTypeId
inner join LeaveStatus on Leaves.StatusId = LeaveStatus.StatusId
inner join Employee_organizationaldetails on Employee_organizationaldetails.EmployeeCode=Employee.EmployeeCode left outer join
Employee ro
on ro.EmployeeCode = ReportingTo
where Leaves.LeaveId = 7295;
You probably don't want the * -- I assume it is just a shorthand for the question. It is better to list columns explicitly, especially because there are duplicate column names.
Possible this be helpful for you -
SELECT
*
, ReportingName = ro.FirstName + ' ' + LastName
FROM (
SELECT *
FROM dbo.Leaves l
WHERE l.LeaveId = 7295
) l
JOIN dbo.LeaveDetails ld ON l.LeaveId = ld.LeaveId
JOIN dbo.Employee e ON l.EmployeeCode = e.EmployeeCode
JOIN dbo.LeaveType lt ON l.LeaveTypeId = lt.LeaveTypeId
JOIN dbo.LeaveStatus ls ON l.StatusId = ls.StatusId
JOIN dbo.Employee_organizationaldetails e2 ON e2.EmployeeCode = e.EmployeeCode
LEFT JOIN dbo.Employee ro ON ro.EmployeeCode = ReportingTo
Lets say that I have tables:
Users
Users_in_Roles
Roles
Rights_in_Roles
Rights
Keys are standard( UserFk, RoleFk, RightFk)
The question is: how to get all users that are in role with right X (id = 100)
I Have no idea how to touch this problem. Please help and sorry for my english.
SELECT [dbo].[System_Users].[Id]
,[UserName]
,[FirstName]
,[LastName]
,[Email]
,RoleFk
,[dbo].[System_Roles].Name
FROM [dbo].[System_Users]
INNER JOIN [dbo].[System_Roles_System_Users]
ON [dbo].[System_Roles_System_Users].UserFk = [dbo].[System_Users].Id
INNER JOIN [dbo].[System_Roles]
ON [dbo].[System_Roles].Id = [dbo].[System_Roles_System_Users].RoleFk
WHERE ?
I tryied sth like that, could you tell me what iw wrong?
SELECT
DISTINCT System_Users.Id,
System_Users.FullName
FROM System_Users
INNER JOIN Dict_Rights_System_Users
ON System_Users.Id = Dict_Rights_System_Users.UserFk
INNER JOIN System_Roles_System_Users
ON System_Roles_System_Users.UserFk = System_Users.Id
WHERE
RightFk = 136
OR
136 IN (SELECT Dict_Rights_System_Roles.RightFk FROM Dict_Rights_System_Roles WHERE
Dict_Rights_System_Roles.RoleFk = System_Roles_System_Users.RoleFk)
ORDER BY System_Users.FullName ASC
You will need to JOIN the tables on the key relationships. The basic structure will be:
select u.Id,
u.UserName,
u.FirstName,
u.LastName,
u.Email,
r.RoleFk,
r.Name RoleName,
rt.Name RightName
from users u
inner join users_in_roles ur
on u.id = ur.userfk
inner join roles r
on ur.rolefk = r.id
inner join rights_in_roles rr
on r.rolefk = rr.rolefk
inner join rights rt
on rr.rightfk = rt.id
where rt.id = 100
If you need help learning JOIN syntax here is a great reference:
A Visual Explanation of SQL Joins
You can try with this:
SELECT *
FROM Users u
WHERE EXISTS (
SELECT ur.RoleFk
FROM Users_in_Roles ur
WHERE u.UserPk = ur.UserFk
AND EXISTS
(
SELECT 1
FROM Rights_in_Roles rr
WHERE rr.RoleFk = ur.RoleFk
AND rr.RightFk = 100
)
)
OR EXISTS (
SELECT 1
FROM Users_Rights uri
WHERE u.UserPk = uri.UserFk
AND uri.RightFk = 100
)
Note that the above query doesn't return RoleFk and Name for the role.
Another approach would be:
SELECT u.Id
,u.UserName
,u.FirstName
,u.LastName
,u.Email
,rr.RoleFk
,r.Name
FROM Users u
-- get users that are in role that has right
LEFT JOIN
Users_in_Roles ur ON
ur.UserFk = u.UserPk
LEFT JOIN
Rights_in_Roles rr ON
rr.RoleFk = ur.RoleFk
AND rr.RightFk = 100
LEFT JOIN
Rights r ON
r.RolePk = rr.RoleFk
-- get users that have a right granted to them directly
LEFT JOIN
Users_Rights uri ON
u.UserPk = uri.UserFk
AND uri.RightFk = 100
WHERE rr.RoleFk IS NOT NULL OR uri.UserFk IS NOT NULL