I'm trying to run an inner join between this same table. What is wrong with my syntax?
(SELECT user_key, bill_number, MAX(payment_date) AS payment_date
FROM billpayment) bpt
INNER JOIN (SELECT * FROM billpayment) bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number
AND bp.payment_date=bpt.payment_date
GROUP BY user_key, bill_number;
It says that the sql command is not properly ended at the parenthesis in 'billpayment)'
SELECT
user_key,
bill_number,
MAX(payment_date) AS payment_date
FROM billpayment bpt
INNER JOIN billpayment bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number AND bp.payment_date=bpt.payment_date
GROUP BY
user_key, bill_number
;
On Oracle Try this:
SELECT *
FROM (SELECT user_key, bill_number, MAX (payment_date) AS payment_date FROM billpayment) bpt
INNER JOIN billpayment bp
ON bp.user_key = bpt.user_key AND bp.bill_number = bpt.bill_number AND bp.payment_date = bpt.payment_date
GROUP BY user_key, bill_number;
Can't test it without the table structure.
How about just using analytic functions?
select bp.*,
max(bp.paymentdate) over (partition by user_key, bill_number) as max_payment_date
from billpayment
If you want the fields on the max payment date:
select bp.*
from (select bp.*,
max(bp.paymentdate) over (partition by user_key, bill_number) as max_paymentdate
from billpayment
) bp
where paymentdate = max_paymentdate;
On mySQL, you can try something like:
SELECT bpt.user_key, bpt.bill_number, MAX(bpt.payment_date) AS payment_date
FROM billpayment bpt
INNER JOIN (SELECT * FROM billpayment) bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number
AND bp.payment_date=bpt.payment_date
GROUP BY bpt.user_key, bpt.bill_number;
I have this query:
SELECT t_ticket.ticketID, t_ticket.addedDate, t_ticket.question,
t_ticket.code, t_ticket.priority, t_actionTicket.addedDateAction, t_actionTicket.title
FROM t_actionTicket INNER JOIN
t_ticket ON t_actionTicket.ticketID_FK = t_ticket.ticketID INNER JOIN
(SELECT ticketID_FK, MAX(addedDateAction) AS maxDate
FROM t_actionTicket AS t_actionTicket_1
WHERE (t_actionTicket.userID_FK <> #userid)
GROUP BY ticketID_FK) AS b ON t_actionTicket.ticketID_FK = b.ticketID_FK AND t_actionTicket.addedDateAction = b.maxDate
WHERE (t_ticket.supporterID_FK IN
(SELECT supporterID
FROM t_Supporter
WHERE (userID_FK = #userid)))
I want to return just the latest record in t_actionTicket table for each row in t_ticket table that t_actionTicket.userID_FK <> #userid.
but I have this error:
The multi-part identifier "t_actionTicket.userID_FK" could not be
bound.
Problem in your query is
FROM t_actionTicket AS t_actionTicket_1
WHERE t_actionTicket.userID_FK <> #userid -- here
You cannot use t_actionTicket alias name inside inner join select query. You need to use t_actionTicket_1. It is possible only in sub-query
Try this better way of doing it
;WITH cte
AS (SELECT t_ticket.ticketID,
t_ticket.addedDate,
t_ticket.question,
t_ticket.code,
t_ticket.priority,
t_actionTicket.addedDateAction,
t_actionTicket.title,
Row_number()
OVER(
partition BY ticketID_FK
ORDER BY addedDateAction DESC) RN
FROM t_actionTicket
INNER JOIN t_ticket
ON t_actionTicket.ticketID_FK = t_ticket.ticketID
WHERE t_ticket.supporterID_FK IN (SELECT supporterID
FROM t_Supporter
WHERE userID_FK = #userid))
SELECT *
FROM cte
WHERE rn = 1
You can write this logic using row_number() instead of additional nested queries:
SELECT t.ticketID, t.addedDate, t.question, t.code, t.priority,
ta.addedDateAction, ta.title AS Expr1
FROM t_Ticket t INNER JOIN
(SELECT ta.*,
ROW_NUMBER() OVER (PARTITION BY ta.ticketID_FK ORDER BY ta.addedDateAction DESC) as seqnum
FROM t_actionTicket ta
) ta
ON t.ticketId = ta.ticketId_FK and ta.seqnum = 1
WHERE t.supporterID_FK IN (SELECT supporterID
FROM t_Supporter
WHERE userID_FK = #userid
);
Note that table aliases make the query easier to write and to read.
Try this query
SELECT t_ticket.ticketID, t_ticket.addedDate, t_ticket.question,
t_ticket.code, t_ticket.priority, t_actionTicket.addedDateAction, t_actionTicket.title
FROM t_actionTicket
INNER JOIN t_ticket ON t_actionTicket.ticketID_FK = t_ticket.ticketID
INNER JOIN (SELECT ticketID_FK, MAX(addedDateAction) AS maxDate
FROM t_actionTicket AS t_actionTicket_1
WHERE (t_actionTicket_1.userID_FK <> #userid)
GROUP BY ticketID_FK) AS b ON t_actionTicket.ticketID_FK = b.ticketID_FK AND t_actionTicket.addedDateAction = b.maxDate
WHERE (t_ticket.supporterID_FK IN
(SELECT supporterID
FROM t_Supporter
WHERE (userID_FK = #userid)))
I have a HISTORY table that has multiple rows for the same record and I am trying to get the latest (closest to today's date) record. I am attempting to group by the closest date but am having a difficult time. Please check out the query below and advise me.
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID
FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, MAX(Qry2.LastActionDate)
does this change help?
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN
(
SELECT SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) as hist_Complaint_ID , MAX(Action_Date) as Action_Date
FROM etc.History
WHERE Field_Name = 'Resolved_Ind'
GROUP BY SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15)
) as o
ON o.hist_Complaint_ID = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, Qry2.LastActionDate
You can use ROW_NUMBER and a CTE to get it:
WITH cte AS (
SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
row_number() over (partition by etc.Complaint.Complaint_ID order by o.Action_Date desc) AS rn
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1
)
SELECT * FROM cte
WHERE rn = 1
My query is taking very long time.
select distinct JobName,
ValidationType,
AppName,
Result,
ResultType,
ErrorWarningDetails,
CvtStartDateTime
from contentvalidationjobdetails with (nolock)
where appname=#AppName
and result=#Result
and (cast(cvtstartdatetime as date) > #Date )
and concat(Jobname,validationtype) not in (
select concat(jobname,validationtype)
from Contentvalidationjobdetails with (nolock)
where appname = #AppName
and CVTStartDateTime = (
select top 1 teststartdatetime
from contentvalidation
where appname=#AppName
and Teststartdatetime<#Date
order by teststartdatetime desc
)
)
I know that the concat(jobname,validationtype) is taking time. how to handle this.
Place the query in FROm section to be executed just once (not for each line in WHERE). Add outer join and leave only records which has no joins.
select distinct JobName,
ValidationType,
AppName,
Result,
ResultType,
ErrorWarningDetails,
CvtStartDateTime
from contentvalidationjobdetails with (nolock)
LEFT OUTER JOIN (
select concat(jobname,validationtype) cnt
from Contentvalidationjobdetails with (nolock)
where appname = #AppName
and CVTStartDateTime = (
select top 1 teststartdatetime
from contentvalidation
where appname=#AppName
and Teststartdatetime<#Date
order by teststartdatetime desc) sub ON concat(Jobname,validationtype)=sub.cnt
where appname=#AppName
and result=#Result
and (cast(cvtstartdatetime as date) > #Date ))
HAVING sub.cnt is null
I just want to know that How to write a CTE containing If Exists in SQl Server ?
I had tried to write a CTE below where i am Using If Exists Statement to select weather the record exist or not .In case if the record does not exist then i am assigning default value but i am getting error
'Incorrect syntax near the keyword 'if'
.' Please help me to fix this error and guide me to write this CTE.
Please find below the CTE which i had written:-
Alter procedure St_Proc_GetTeamProductionReport
#mindate DateTime,
#maxdate DateTIme,
#userID varchar(50)
as
Begin
set NoCount on;
with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
if exists
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=#userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
else
(
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=#userID) as UserECode,
(select UserName from Userinfo where userid=#userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=#userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment
)
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment from ProductionCTE where RoleID=1
end
GO
When i am removing this If Exist statement then the CTE is working fine but after adding the IF Exists statement it is having error.
You can't use IF EXISTS in this way. A common table expression must only contain a single select statement, it's not possible to say if condition SELECT THIS else SELECT THAT.
It looks like you are trying to add an additional created row to a resultset returned by a query. You could achieve this by implementing the CTE as a table-valued function that would return the single new row.
http://msdn.microsoft.com/en-gb/library/ms191165(v=sql.105).aspx
If you want to construct a UNION where you only get a result from the second SELECT if the first SELECT returns no rows, you can achieve this using RANK(). So, you can place your real query in the first SELECT and the desired default values in the second, and achieve the results you want.
I don't have your tables and data, so I'm not going to attempt to re-write your query. But I'll illustrate with this:
;With WithDefaults as (
select name,0 as Rank from sys.objects
union all
select 'abc',1 --Default if no results
), Ranked as (
select *,RANK() OVER (ORDER BY Rank) as Rnk from WithDefaults
)
select * from Ranked where Rnk = 1
Returns (on a mostly empty DB I tried it on) 98 results, of which none had the name abc. If we force the first SELECT to return no results:
select name,0 as Rank from sys.objects where 1 = 2
We now get a single row result with the name abc.
Hopefully, you can see how this could apply to your original query.
You can't use IF EXISTS in CTE. But you can modify logic of function
Example:
alter procedure St_Proc_GetTeamProductionReport
#mindate DateTime,
#maxdate DateTIme,
#userID varchar(50)
as
Begin
set NoCount on;
;with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment, 1 AS cnt
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=#userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
UNION ALL
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=#userID) as UserECode,
(select UserName from Userinfo where userid=#userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=#userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment, 0
), ProductionCTE2 AS
(
SELECT TOP(SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE COUNT(*) END FROM ProductionCTE WHERE cnt = 1)
CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureofWorkName,
RegionProjectName,Countyname,WorktypeName,TaskName,VolumeProcessed,Timespent,Comment
FROM ProductionCTE2
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment
from ProductionCTE2
where RoleID=1
end