select user doesn't contain a record in other table sql query - sql

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.

Related

Get all data for an entity from another table in one query

I have this query
select *
from (
select c.*,p.name as project_name,u.firstname || ' ' || u.lastname as fullname, u.email as owner_email, u.payment_method, u as user, u.id as user_id, u.api_id, u.api_key,
v.name as vendor_name, v.exid as vendor_id, s.number as sim_number, vm.exid as vendor_model_id, vm.name as vendor_model_name, cr.status as is_recording,
cr.storage_duration as cloud_recording_storage_duration, cr.schedule as schedule, cr.frequency as frequency,
(select count(id) as total from camera_shares cs where c.id=cs.camera_id) as total_share
from cameras c
inner JOIN users u on c.owner_id = u.id
left JOIN projects p on c.project_id = p.id
left JOIN sims s on c.id = s.camera_id
left JOIN vendor_models vm on c.model_id = vm.id
left JOIN vendors v on vm.vendor_id = v.id
left JOIN cloud_recordings cr on c.id = cr.camera_id
) c
this gives me all cameras and with all relevant values which I require.
now there is another table, snapshot_extractors and it has a relation with the camera on id and camera_id in extractors table, as one camera can have more than 1 extractors.
In the above query, I want to get all extraction for one camera, I can do it in a separate query, but is it possible to get all extractions in the above query as an array of all extractions for a camera?
You can use another correlated subquery:
(select array_agg(e.extraction)
from snapshot_extractors e
where e.camera_id = c.camera_id
)

Too many results in query

I'm fetching some data from our database in MSSQL. Out of this data I want to determine who created the client entry and who took the first payment from this client.
There can be many payment entries for a client on a single booking/enquiry and at the moment, my query shows results for each payment. How can I limit the output to only show the first payment entry?
My query:
SELECT
c.FirstName,
c.LastName,
c.PostalCode,
o.OriginOfEnquiry,
s.SuperOriginName,
c.DateOfCreation,
DATEDIFF(day, c.DateOfCreation, p.DateOfCreation) AS DaysToPayment,
pc.PackageName,
CONCAT(u.FirstName, ' ', u.LastName) AS CreateUser,
(SELECT CONCAT(u.FirstName, ' ', u.LastName)
WHERE u.UserID = p.UserID ) AS PaymentUser
FROM tblBookings b
INNER JOIN tblPayments p
ON b.BookingID = p.BookingID
INNER JOIN tblEnquiries e
ON e.EnquiryID = b.EnquiryID
INNER JOIN tblCustomers c
ON c.CustomerID = e.CustomerID
INNER JOIN tblOrigins o
ON o.OriginID = e.OriginID
INNER JOIN tblSuperOrigins s
ON s.SuperOriginID = o.SuperOriginID
INNER JOIN tblBookingPackages bp
ON bp.bookingID = p.BookingID
INNER JOIN tblPackages pc
ON pc.PackageID = bp.packageID
INNER JOIN tblUsers u
ON u.UserID = c.UserID
WHERE c.DateOfCreation >= '2016-06-01' AND c.DateOfCreation < '2016-06-30'
AND p.PaymentStatusID IN (1,2)
AND e.CustomerID = c.CustomerID
AND p.DeleteMark != 1
AND c.DeleteMark != 1
AND b.DeleteMark != 1
;
I tried adding a "TOP 1" to the nested select statement for PaymentUser, but it made no difference.
you can use cross apply with top 1:
FROM tblBookings b
cross apply
(select top 1 * from tblPayments p where b.BookingID = p.BookingID) as p
Instead of table tblPayments specify sub-query like this:
(SELECT TOP 1 BookingID, UserID, DateOfCreation
FROM tblPayments
WHERE DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation) as p
I'm assuming that tblPayments has a primary key column ID. If it is true, you can use this statment:
FROM tblBookings b
INNER JOIN tblPayments p ON p.ID = (
SELECT TOP 1 ID
FROM tblPayments
WHERE BookingID = b.BookingID
AND DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation)

List of users in a JIRA Project

Can someone please help me with a SQL to retrieve users associated to a JIRA project?
SELECT A.ROLETYPEPARAMETER AS USERNAME, R.NAME AS ROLENAME, P.PKEY || ' - ' || P.PNAME AS PROJECTNAME
FROM PROJECTROLEACTOR A
INNER JOIN PROJECTROLE R ON A.PROJECTROLEID = R.ID
INNER JOIN PROJECT P ON A.PID = P.ID
ORDER BY 3, 1, 2;
or to just aggregate the users per project:
SELECT DISTINCT P.PKEY, LISTAGG(A.ROLETYPEPARAMETER, ',') WITHIN GROUP(ORDER BY A.ROLETYPEPARAMETER ASC) OVER(PARTITION BY P.PKEY) AS USERNAMES
FROM PROJECTROLEACTOR A
INNER JOIN PROJECTROLE R ON A.PROJECTROLEID = R.ID
INNER JOIN PROJECT P ON A.PID = P.ID
GROUP BY P.PKEY, A.ROLETYPEPARAMETER;;
For Jira 6, the correct MySQL syntax is:
SELECT
A.ROLETYPEPARAMETER AS USERNAME,
R.NAME AS ROLENAME, CONCAT(P.pkey, ' - ', P.pname) AS PROJECTNAME
FROM projectroleactor A
INNER JOIN projectrole R ON A.PROJECTROLEID = R.ID
INNER JOIN project P ON A.PID = P.ID
ORDER BY 3, 1, 2
NOTE: field names are case-sensitive

Optimizing SQL join single column with multiple columns in another table

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)

SQL join query result issue

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