Need to rewrite sql query - sql

I am new to query and I need help writing a query.
I want to Select
Project_Post.ProjectPost
from Project_Post
Where Project_Post.ProfileId = (User_profile.ProfileID Where User_profile.UserId = #username)
And Project_Post.Project date is less than Project_Follower.LastPageView
Where Project_Follower.profileId = (User_profile.ProfileID Where User_profile.UserId = #username)
Thank you.

Should be something like that:
SELECT col1, col2 -- specify what you need
FROM Project_Post pp
INNER JOIN User_profile up ON up.ProfileId = pp.ProfileId
INNER JOIN Project_Follower pf ON pf.profileId = up.ProfileID
WHERE
pp.Project_date < pf.LastPageView AND
pp.ProfileId = (
SELECT ProfileID
FROM User_profile
WHERE UserId = #username
) AND
pf.profileId = (
SELECT ProfileID
FROM User_profile
WHERE UserId = #username
)

It will be better if you give us the structure of tables, but depend on your query, this something like :
SELECT pp.ProjectPost
FROM Project_Post AS pp WITH(NOLOCK)
INNER JOIN User_Profile AS up WITH(NOLOCK) ON pp.ProfileID = up.ProfileID
INNER JOIN Project_Follower AS pf WITH(NOLOCK) ON pp.ProfileID = pf.ProfileID
WHERE up.Username = #Username
AND pp.Project_Date < pf.LastPageView

Related

Where Clause Using Conditional Statement

i have query below
SELECT #RoleUser = MR.Code FROM MasterRole MR INNER JOIN MasterUsersRole MUR ON MR.Id = MUR.RoleId
INNER JOIN MasterUsers MU ON Mu.UserCode = MUR.UserCode
WHERE MU.UserCode = #UserLoginID
select 1 Num
, MyHistory.ID
, MyHistory.RequestNumber
, MyHistory.FlowID
, MyHistory.FlowProcessStatusID
from
(
select *
from Requests R
inner join
(
--DECLARE #UserLoginID nvarchar(200) = 'dum.testing.3'
select distinct
RequestID
from dbo.RequestTrackingHistory RTH
where IIF(#UserLoginID = 'admin', #UserLoginID, RTH.CreatedBy) = #UserLoginID
OR ( CreatedBy IN
SELECT Mu.UserCode from MasterUsers MU
INNER JOIN MasterUsersRole MUR ON MU.UserCode = MUR.UserCode
INNER JOIN MasterRole MR ON MUR.RoleId = MR.Id
WHERE MR.Code = #RoleUser
)
)
) RT on R.ID = RT.RequestID
) as MyHistory
inner join MasterFlow F on MyHistory.FlowID = F.ID
inner join
(
select FP.ID
, FP.Name
, FP.AssignType
, FP.AssignTo
, FP.IsStart
, case FP.AssignType
when 'GROUP' then
G.Name
end as 'AssignToName'
from MasterFlowProcess FP
left join dbo.MasterRole G on FP.AssignTo = G.ID and FP.AssignType = 'GROUP'
) FP on MyHistory.FlowProcessID = FP.ID
inner join MasterFlowProcessStatus FPS on MyHistory.FlowProcessStatusID = FPS.ID
left join MasterFlowProcessStatusNext FPSN on FPS.ID = FPSN.ProcessStatusFlowID
left join MasterFlowProcess FPN on FPSN.NextProcessFlowID = FPN.ID
left JOIN MasterRole MR ON MR.Id = FPN.AssignTo
left join MasterUsersRole MUR on MR.Id = MUR.RoleId
left join MasterUsers MURO on MUR.UserCode = MURO.UserCode
inner join MasterUsers UC on MyHistory.CreatedBy = UC.UserCode
left join MasterUsers UU on MyHistory.UpdatedBy = UU.UserCode
LEFT JOIN RequestMT RMT ON MyHistory.ID = RMT.RequestID
LEFT JOIN RequestGT RGT ON MyHistory.ID = RGT.RequestID
left join (SELECT sum(QtyCU) countQty , RequestId from dbo.RequestGTDetail where IsActive = 1 group by RequestId) RGTD on RGTD.RequestId = RGT.RequestId
left join (SELECT sum(QtyPCS) countQty , RequestId from dbo.RequestMTDetail where IsActive = 1 group by RequestId) RMTD on RMTD.RequestId = RMT.RequestId
left join (SELECT COUNT(IIF(returnable = 0, returnable, null)) countReturnable , RequestId from dbo.RequestMTDetail group by RequestId) RMTR on RMTR.RequestId = RMT.RequestId
left JOIN dbo.MasterDistributor md ON md.Code = RGT.CustId or md.Code = RMT.CustId
left JOIN dbo.MasterUsersDistributor MUD ON MUD.UserCode = MURO.UserCode AND md.Code = MUD.DistributorCode
LEFT JOIN dbo.MasterReason MRMT ON RMT.ReasonId = MRMT.Id
LEFT JOIN dbo.MasterReason MRGT ON RGT.ReasonId = MRGT.Id
LEFT JOIN dbo.MasterDistributorGroup MDG ON MDG.Id = MD.GroupId
OUTER APPLY dbo.FnGetHistoryApproveDate(MyHistory.Id) AS x
where REPLACE(FPS.Name, '#Requestor', uc.Name) <> 'DRAFT'
AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID)
i want to add some logic in where clause
this line
==> AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID)
it depend on the #RoleUser variable, if #RoleUser IN ('A','B') then where clause above is executed, but if #RoleUser Not IN ('A','B') where clause not executed
i,m trying this where clause
AND IIF(#RoleUser IN ('A','B'), MUD.DistributorCode, #RoleUser) IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = IIF(#RoleUser IN ('A','B'), #UserLoginID, NULL))
it didn't work, only executed if #RoleUser IS ('A','B') other than that it return 0 record
any help or advice is really appreciated
thank you
The cleanest way I'm implemented these kind of crazy rules is a
holderTable
and a countVariable against the holder table.
I'll give a generic examples.
This is a "approach" and "philosophy", not a specific answer....with complex WHERE clauses.
DECLARE #customerCountryCount int
DECLARE #customerCountry TABLE ( CountryName varchar(15) )
if ( "the moon is blue on tuesday" ) /* << whatever rules you have */
BEGIN
INSERT INTO #customerCountry SELECT "Honduras" UNION ALL SELECT "Malaysia"
END
if ( "favorite color = green" ) /* << whatever rules you have */
BEGIN
INSERT INTO #customerCountry SELECT "Greenland" UNION ALL SELECT "Peru"
END
SELECT #customerCountryCount = COUNT(*) FROM #customerCountry
Select * from dbo.Customers c
WHERE
(#customerCountryCount = 0)
OR
( exists (select null from #customerCountry innerVariableTable where UPPER(innerVariableTable.CountryName) = UPPER(c.Country) ))
)
This way, instead of putting all the "twisted logic" in an overly complex WHERE statement..... you have "separation of concerns"...
Your inserts into #customerCountry are separated from your use of #customerCountry.
And you have the #customerCountryCount "trick" to distinguish when nothing was used.
You can add a #customerCountryNotExists table as well, and code it to where not exists.
As a side note, you may want to try using a #temp table (instead of a #variabletable (#customerCountry above)... and performance test these 2 options.
There is no "single answer". You have to "try it out".
And many many variables go into #temp table performance (from a sql-server SETUP, not "how you code a stored procedure". That is way outside the scope of this question.
Here is a SOF link to "safe" #temp table usage.
Temporary table in SQL server causing ' There is already an object named' error

SQL IN clause in where condition causing performance issue with large data

The following query works fine in my database but it is giving huge performance issues in customer DB. I know that I am using the IN clause in the where condition which is giving me this problem. But I don't know how to fix this.
declare #AccountId int
set #AccountId = 1200
declare #IsLinkedAccountsNotes bit
set #IsLinkedAccountsNotes =1
declare #EventType varchar(100)
set #EventType = ''
SELECT
u.loginName as InteractionLoginName,
u.userName as InteractionUserName,
e.*
FROM
lat.events e
INNER JOIN dbo.MasterEvents me ON me.EventId = e.EventId
LEFT JOIN dbo.Users u ON e.UserId = u.ID
WHERE
(me.AccountId = #AccountId OR
(#IsLinkedAccountsNotes = 1 AND me.AccountId IN (SELECT DISTINCT [number] FROM dbo.Linking_LinkedAccounts WHERE linked_number = #AccountId) AND e.EventType = 'AccountNoteAdded'))
I know that the second condition in where clause is causing the problem. And I have seen in various posts that using a join will solve this problem. But I am not getting how to use join inside where condition.
Or is there any other approach for the same.
Please help.
Your problem is likely that this is a "catch all query". You can try splitting the cases out as below
SELECT u.loginName AS InteractionLoginName,
u.userName AS InteractionUserName,
e.*
FROM lat.events e
INNER JOIN dbo.MasterEvents me
ON me.EventId = e.EventId
LEFT JOIN dbo.Users u
ON e.UserId = u.ID
WHERE me.AccountId = #AccountId
UNION ALL
SELECT u.loginName AS InteractionLoginName,
u.userName AS InteractionUserName,
e.*
FROM lat.events e
INNER JOIN dbo.MasterEvents me
ON me.EventId = e.EventId
LEFT JOIN dbo.Users u
ON e.UserId = u.ID
WHERE #IsLinkedAccountsNotes = 1
AND e.EventType = 'AccountNoteAdded'
AND me.AccountId IN (SELECT [number]
FROM dbo.Linking_LinkedAccounts
WHERE linked_number = #AccountId
AND [number] <> #AccountId)
Could try something like
JOIN (SELECT DISTINCT [number] FROM dbo.Linking_LinkedAccounts WHERE linked_number = #AccountId) lla ON lla.number = me.AccountId
LEFT JOIN and filter out null values in where condition.
EXISTS instead of IN.

Better ways to write this SQL Query

I have the below table structure
Users (PK - UserId)
System (PK - SystemId)
SystemRoles (PK-SystemRoleId, FK - SystemId)
UserRoles (PK-UserId & SystemRoleId, FK-SystemRoleId, FK-UserId)
Users can have access to different Systems and one System can have different SystemRoles defined.
Now, I need to delete Users who have SystemRoles assigned to them ONLY for a specific System(s). If they have SystemRoles defined for other Systems, they should not be deleted.
I have come up the below query to identify the records that are eligible for delete but think this can surely be optimized. Any suggestions?
SELECT U.*
FROM
(
SELECT
distinct UR.UserID
FROM
dbo.UserRole UR
INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID)
INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID)
WHERE
S.SystemName = 'ABC' OR S.SystemName = 'XYZ'
) T
INNER JOIN dbo.[User] U ON (U.UserID = T.UserID)
WHERE T.UserID NOT IN
(
select
distinct UR.UserID
from
dbo.[UserRole] UR
INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID)
INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID)
WHERE
S.SystemName <> 'ABC'
AND S.SystemName <> 'XYZ'
)
something like this?
select userid from (
SELECT
UR.UserID,
max(case when (S.SystemName = 'ABC' OR S.SystemName = 'XYZ')
then 1 else 0 end) as kill,
max(case when (S.SystemName <> 'ABC' AND S.SystemName <> 'XYZ')
then 1 else 0 end) as keep
FROM
dbo.UserRole UR
INNER JOIN dbo.SystemRole SR ON (SR.SystemRoleID = UR.SystemRoleID)
INNER JOIN dbo.[System] S ON (S.SystemID = SR.SystemID)
group by UR.UserID
) u where kill = 1 and keep = 0
This sort of structure will get you the records you need.
select yourfields -- or delete
from userroles
where userid in
(select userid
from userroles join etc
where system.name = the one you want
except
select userid
from userroles join etc
where system.name <> the one you want
)

WHERE clause not functioning as expected

I am trying to join some tables to receive some data and it is not working as expected. Here is my query:
SELECT USR.PK_User AS PKUser
,USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR ON ASPU.UserId = ASPUIR.UserId
WHERE ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
Nothing is being returned from this query. But if I do:
SELECT * FROM [aspnet_UsersInRoles] WHERE RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
I get 76 selected rows. If I just do:
SELECT USR.PK_User AS PKUser
,USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR ON ASPU.UserId = ASPUIR.UserId
I get the expected rows returned. Additionally, if I add:
WHERE ASPUIR.RoleId IS NULL
I get rows back.
What am I doing wrong?
You need the condition in the ON not the WHERE.
Otherwise you just make it back into an inner join effectively.
SELECT USR.PK_User AS PKUser,
USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU
ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR
ON ASPU.UserId = ASPUIR.UserId
AND ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
Try this:-
SELECT USR.PK_User AS PKUser,
USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU
ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR
ON ASPU.UserId = ASPUIR.UserId
AND ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'

SQL SELECT statement with users, roles and rights

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