Creating a new column based on values from another field-same table - sql-server

How do you take this case statement and insert it into a complex query that's doing alot of left joins? I want to do exactly what this does--but I can't figure out where to add it in my query.
Select
CASE
WHEN [Activity Type] = 'A' THEN
CASE WHEN MonitorA_ID is NULL
OR MonitorA_Date is NULL
OR MonitorA_Region is NULL
THEN 1 ELSE 0 END
END as 'A_Chk'
From Table
where I thought I could do it, won't work-
LEFT JOIN [dbo].[LABEL] LABEL on ISSUE = ji.id --1:M (possible) for each issue
--Custom Fields: Story Points
let me know if more of the query is needed.
added full query:
select
pt.pname as project
, pt.pkey as projectkey
, ji.issuenum
, ji.assignee
, ji.creator
,un.lower_user_name as updated_creator
,un_1.lower_user_name as updated_assignee
,un_2.lower_user_name as updated_reporter
, ji.reporter
, p.pname as Priority
, it.pname as Type
, iss.pname as Status
, r.pname as Resolution
, ji.summary
, ji.created
, ji.updated
, ji.duedate
, ji.resolutiondate
, cfo1.customvalue as Team
, cfo2.customvalue as impact
, cfo3.customvalue as found
, cfo4.customvalue as environment
,cfo5.name as sprint
, cfv6.stringvalue as remedyticket
, cfv7.stringvalue as apmId
--, cf.CUSTOMFIELD
, pv1.vname as issuefixverion
, pv1.released as issuefixversionreleasestatus
, pv1.releasedate as issuefixversionreleasedate
, pv1.sequence as issuefixversionsequence
, pv2.vname as issueversion
, pv2.released as issueversionreleasestatus
, pv2.releasedate as issueversionreleasedate
, c3.cname as Delivery_Platform
,CF.[CUSTOMFIELD] as STORY_PNT_CSTM_FLD_ID
,CF.[NUMBERVALUE] as STORY_POINTS
,LABEL.[LABEL] as Label--will have multiple records per issue if more than 1 label is assigned
,ji.[ID] as ISSUE_ID_NUM
,ji.[Archived]
, cfv.STRINGVALUE
, cfv.ISSUE as ISUUEIdNum
, cfo.customvalue
, cfo.ID as IDCFO
, cf1.ID as IDCF
,datediff(hour,ji.[CREATED],ji.[RESOLUTIONDATE]) as 'Hours Impacted'
,datediff(hour,ji.[CREATED],ji.[RESOLUTIONDATE]) /24 as 'Days per Ticket'
,avg(datediff(day, ji.[CREATED], ji.[RESOLUTIONDATE])) as 'Avg Age'
from [dbo].[jiraissue] ji
inner join [dbo].[issuetype] it on it.id = ji.issuetype
inner join [dbo].[project] pt on pt.id = ji.project
inner join [dbo].[issuestatus] iss on iss.id = ji.issuestatus
left join [dbo].[app_user] un on ji.creator=un.user_key
left join [dbo].[app_user] un_1 on ji.assignee=un_1.user_key
left join [dbo].[app_user] un_2 on ji.REPORTER=un_2.user_key
left join [dbo].resolution r on r.id = ji.resolution
left join [dbo].[priority] p on p.sequence = ji.priority
LEFT JOIN [dbo].[LABEL] LABEL on ISSUE = ji.id --1:M (possible) for each issue
--Custom Fields: Story Points
LEFT JOIN [dbo].[customfieldvalue] CF on CF.[ISSUE] = issuenum AND CF.CUSTOMFIELD = ' ' --Story Points Field
Left join [dbo].[customfieldvalue] cfv1
on cfv1.issue =ji.id
and cfv1.customfield = ( select id from customfield where cfname = 'team ( ')
left join [dbo].[customfieldoption] cfo1 on cast(cfo1.id as varchar) = cfv1.stringvalue
left join [dbo].[customfieldvalue] cfv2
on cfv2.issue =ji.id
and cfv2.customfield = ( select id from customfield where cfname = 'impact ( ')
left join [dbo].[customfieldoption] cfo2 on cast(cfo2.id as varchar) = cfv2.stringvalue
left join [dbo].[customfieldvalue] cfv3 on
cfv3.issue =ji.id
and cfv3.customfield = ( select id from customfield where cfname = 'found ( ')
left join [dbo].[customfieldoption] cfo3 on cast(cfo3.id as varchar) = cfv3.stringvalue
left join [dbo].[customfieldvalue] cfv4
on cfv4.issue =ji.id
and cfv4.customfield = ( select id from customfield where cfname = 'environment ( ')
left join [dbo].[customfieldoption] cfo4 on cast(cfo4.id as varchar) = cfv4.stringvalue
left join [dbo].[customfieldvalue] cfv5
on cfv5.issue =ji.id
and cfv5.customfield = ( select id from customfield where cfname = 'sprint')
left join [dbo].[ao_60db71_sprint] cfo5 on cast(cfo5.id as varchar) = cfv5.stringvalue
left join [dbo].[customfieldvalue] cfv6
on cfv6.issue =ji.id
and cfv6.customfield = ( select id from customfield where cfname = 'remedy ticket')
left join [dbo].[customfieldvalue] cfv7
on cfv7.issue =ji.id
and cfv7.customfield = ( select id from customfield where cfname = 'APM ID')
left join customfieldvalue cfv on ji.id = cfv.issue -- joins table 1 to table 2 based on jira id
LEFT JOIN customfieldoption cfo on cfv.stringvalue = (cast(cfo.id as varchar)) -- joins table 2 to table 3 based on stringvalue ( )
Left Join customfield cf1 on cfv.stringvalue = (cast(cf.id as varchar)) -- joins table 2 to table 4 based on stringvalue ( )
left join [dbo].nodeassociation na1 on na1.source_node_id = ji.id and na1.association_type ='issuefixversion'
left join [dbo].projectversion pv1 on pv1.id = na1.sink_node_id
left join [dbo].nodeassociation na2 on na2.source_node_id = ji.id and na2.association_type ='issueversion'
left join [dbo].projectversion pv2 on pv2.id = na2.sink_node_id
left join [dbo].nodeassociation na3 on na3.source_node_id = ji.id and na3.association_type ='issuecomponent'
left join dbo.[component] c3 on c3.id = na3.sink_node_id
where pt.pkey = ' ' OR
pt.pkey = ' '
and ji.archived='N'
group by pt.pname
, pt.pkey
, ji.issuenum
, ji.assignee
, ji.creator
,un.lower_user_name
,un_1.lower_user_name
,un_2.lower_user_name
, ji.reporter
, p.pname
, it.pname
, iss.pname
, r.pname
, ji.summary
, ji.created
, ji.updated
, ji.duedate
, ji.resolutiondate
, cfo1.customvalue
, cfo2.customvalue
, cfo3.customvalue
, cfo4.customvalue
, cfo5.name
, cfv6.stringvalue
, cfv7.stringvalue
, pv1.vname
, pv1.released
, pv1.releasedate
, pv1.sequence
, pv2.vname
, pv2.released
, pv2.releasedate
, c3.cname
,CF.[CUSTOMFIELD]
,CF.[NUMBERVALUE]
,LABEL.[LABEL]
,ji.[ID]
,ji.archived
, cfv.STRINGVALUE
, cfv.ISSUE
, cfo.customvalue
, cfo.ID
, cf1.ID

Related

Using ROW_NUMBER() to remove duplicates in SQL server

My current query returns too many lines per Subject_ID, so I want to use ROW_NUMBER() to limit the resulting set to 1 line per Subject_ID. I've added this line to my SELECT statement:
, ROW_NUMBER() over(partition by CS.Subject_ID order by CS.Subject_ID) rn
But when I try to put WHERE rn = 1 anywhere in the FROM statement, I get the error:
Incorrect syntax near the keyword 'WHERE'
And when I try to change it to AND rn = 1 (and add it on to another AND/OR line) I get the error:
Invalid column name 'rn'
So my first question is: When I add a field to my SELECT statement using that ROW_NUMBER() line, what table does this column belong to? Do I need to append it to something like Table.rn? My second question is where should I put this rn = 1 line and how should I write it in?
Full query:
SELECT
Groups.Group_Name
, CT.Created
, CT.Subject_Id
INTO #temp
FROM SubjectZ_Task CT
INNER JOIN
SubjectZ_Task_Users On CT.SubjectZ_Task_Id = SubjectZ_Task_Users.SubjectZ_Task_Id
INNER JOIN
Groups ON Groups.Group_ID = SubjectZ_Task_Users.Group_Reference
WHERE Group_Name LIKE 'Team 1'
AND CT.Created >= '1/1/2019' AND CT.Created < DATEADD(Day,1,'12/31/2019')
GROUP BY Groups.group_name, CT.Created, CT.Subject_ID
SELECT
CT.Group_Name
, CT.Created
, CS.Topic_Start_Date
, CS.Subject_ID
, P.FirstName
, P.LastName
, CS.Subject_Match_ID
, SubjectX.Firstname AS SubjectX_firstname
, CS.SubjectY
, AEC.AEC AS Max_AEC
, SubjectX.Email_id As SubjectX_Email
, Phone.Phone
, ROW_NUMBER() over(partition by CS.Subject_ID order by CS.Subject_ID) rn
FROM #temp CT
LEFT JOIN QE_Topic_Summary CS ON CS.Subject_ID = CT.Subject_Id
AND (Topic_Status LIKE 'In Progress'
OR Topic_Status LIKE 'Pending')
AND CS.Topic_Start_Date >= DATEADD(Day,-60,CT.Created) AND CS.Topic_Start_Date <= DATEADD(Day,60,CT.Created)
INNER JOIN Subjects P ON P.Subject_ID = CS.Subject_ID
LEFT JOIN Subjects SubjectX ON SubjectX.Subject_ID = CS.SubjectX_ID
LEFT JOIN QE_TB_MAX_AEC AEC ON AEC.Subject_ID = CS.Subject_ID
INNER JOIN Subject_Identifiers PI ON PI.Subject_ID = P.Subject_ID
LEFT JOIN Subject_Identifiers PIP ON PIP.Subject_ID = SubjectX.Subject_ID
LEFT JOIN Subject_Phone Phone On Phone.Subject_ID = P.Subject_ID WHERE Phone.Voice = 1
drop table #temp
I don't see a reference to rn in your WHERE clause, but my guess is that you need to wrap it in another query like so:
SELECT *
FROM(
SELECT
CT.Group_Name
, CT.Created
, CS.Topic_Start_Date
, CS.Subject_ID
, P.FirstName
, P.LastName
, CS.Subject_Match_ID
, SubjectX.Firstname AS SubjectX_firstname
, CS.SubjectY
, AEC.AEC AS Max_AEC
, SubjectX.Email_id As SubjectX_Email
, Phone.Phone
, ROW_NUMBER() over(partition by CS.Subject_ID order by CS.Subject_ID) rn
FROM #temp CT
LEFT JOIN QE_Topic_Summary CS ON CS.Subject_ID = CT.Subject_Id
AND (Topic_Status LIKE 'In Progress'
OR Topic_Status LIKE 'Pending')
AND CS.Topic_Start_Date >= DATEADD(Day,-60,CT.Created) AND CS.Topic_Start_Date <= DATEADD(Day,60,CT.Created)
INNER JOIN Subjects P ON P.Subject_ID = CS.Subject_ID
LEFT JOIN Subjects SubjectX ON SubjectX.Subject_ID = CS.SubjectX_ID
LEFT JOIN QE_TB_MAX_AEC AEC ON AEC.Subject_ID = CS.Subject_ID
INNER JOIN Subject_Identifiers PI ON PI.Subject_ID = P.Subject_ID
LEFT JOIN Subject_Identifiers PIP ON PIP.Subject_ID = SubjectX.Subject_ID
LEFT JOIN Subject_Phone Phone On Phone.Subject_ID = P.Subject_ID
WHERE Phone.Voice = 1
)t
WHERE t.rn = 1

Duplicate records with Multiple joins

I had written a join query statement. that statement returns me multiple(duplicate) row again even though I'm having only single record on that.
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
For that I'm getting the result as second row as duplicate :
observe the result
Try this once it may help you
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
;with cte as (
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
)
select distinct EmployerContribution,
CatchUpValue ,Tier,planYear,Ischecked,EmployeeContribute,Id ,Value ,HSALmitId from cte
Please change your where condition as below:
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098'
and bhsac.PlanInfoId=38044
and oems.EndDt > GETDATE()

Staff column for my stored procedure does not always generate information

So my stored procedure has a staff column that should be generating a staff name from my Employee table. The staff name only shows up on for some of the rows. Can anyone take a look and see where my error is here:
BEGIN
IF EXISTS (SELECT 1 FROM [user] (NOLOCK)
WHERE [user].ID = #UserID
AND [user].BrandID IS NULL AND [user].SpaID IS NULL)
BEGIN
DECLARE #OrderStatusID_Completed int, #OrderStatusID_Shipped int
SET #OrderStatusID_Shipped = 4
SET #OrderStatusID_Completed = 2
SELECT
CAST('' AS varchar(50)) AS ErrMsg
, o.OrderNumber
, Customer.GUID AS CustomerGUID
, OrderItem_View.DateCreated AS ItemDate
, COALESCE(MasterProductVariant.SKU, ProductVariant.SKU, Treatment.SKU) AS SKU
, DynamicPrice.FinalPrice AS Price
--, COALESCE(MasterProductVariant.OriginalPrice, ProductVariant.OriginalPrice, Treatment.Price) AS Price
, ISNULL(Employee.FirstName,'') + ' ' + ISNULL(Employee.LastName,'') AS Staff
, COALESCE(Product.Name, Treatment.Name) AS Item
, NULL AS Note
FROM
[Order] o (Nolock)
LEFT JOIN
Customer (Nolock) ON o.CustomerID = Customer.ID
INNER JOIN
OrderItem_View (nolock) ON OrderItem_View.OrderID = o.ID
LEFT JOIN
DynamicPrice (nolock) ON OrderItem_View.DynamicPriceID = DynamicPrice.ID
LEFT JOIN
AppointmentTreatment WITH (NOLOCK) ON AppointmentTreatment.ID = OrderItem_View.AppointmentTreatmentID
LEFT JOIN
Employee (NOLOCK) ON Employee.ID = COALESCE(OrderItem_View.EmployeeID, OrderItem_View.Employee2ID, AppointmentTreatment.EmployeeID)
LEFT JOIN
Treatment_View Treatment (nolock) ON Treatment.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant (NOLOCK)
LEFT JOIN
Product (NOLOCK) ON Product.ID = ProductVariant.ProductID
ON ProductVariant.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant MasterProductVariant (NOLOCK) ON ProductVariant.MasterRecordID = MasterProductVariant.ID
WHERE
o.SpaID = #SpaID
AND o.IsDeleted = 0
AND o.DateCompleted >= CONVERT(DATETIME,0)
AND o.DateCompleted < GetDate()
AND o.StatusID IN (#OrderStatusID_Completed,#OrderStatusID_Shipped)
END
ELSE
SELECT CAST('Insufficient rights.' AS VARCHAR(50)) AS ErrMsg
END
It has to be in the coalesce function. Somewhere between these three - you aren't getting a value
OrderItem_View.EmployeeID
OrderItem_View.Employee2ID
AppointmentTreatment.EmployeeID
So run OrderItem_View by itself and see if there are instances where EmployeeID or Employee2ID is ever null. If so, then try to determine what employees are missing. IF there are employees missing, are they also missing in the AppointmentTreatment table? If so then therein lies the problem.

SQLServer reference outer query

Is it possible to reference an outer query from an inner query in the context of a join? The "where (sid.ItemID = i.itemID)" of the inner query is giving me an error. I thought I did this in the past so I search through all my stored procs but apparently I did some kind of substitution to get it to work. I suspect I can delete that line and it will work but is it more effecient with that inner where clause?
SELECT departmentName
, supplierName
, so.SalesOrderID
, ss.warehouseInvoiceNo
, ss.transactionNo
, ss.storeID
, s.storeName
, s.storeNo
, tr.transactionDate
, p.period
, sooos.salesOrderID
, sooos.salesOrderOutOfStockID
, sooos.itemID
, i.itemNo
, i.itemName
, i.pack
, i.unitSize
, quantity
, wi.available
FROM SalesOrderOutOfStock sooos
JOIN Item AS i ON i.ItemID = sooos.ItemID
JOIN SalesOrder so ON so.SalesOrderID = sooos.SalesOrderID
JOIN WarehouseInventory wi ON wi.ItemID = sooos.ItemID
JOIN Store s ON s.StoreID = so.StoreID
JOIN InvoiceOrderRelationship ior ON ior.SalesOrderID = so.SalesOrderID
JOIN StockSale ss ON ss.WarehouseInvoiceNo = ior.WarehouseInvoiceNo
JOIN TransactionRegister tr ON tr.TransactionNo = ss.TransactionNo
JOIN Period p ON p.PeriodID = tr.PeriodID
JOIN Department d ON d.DepartmentID = i.DepartmentID
LEFT OUTER JOIN (SELECT TOP 1 itemID
, supplierID
FROM SupplierInvoiceDetail sid
JOIN SupplierInvoice si ON si.SupplierInvoiceID = sid.SupplierInvoiceID
--where (sid.ItemID = i.itemID)
order by InvoiceDate desc
--NEED AN ORDER BY HERE
) AS lastSupplier ON lastSupplier.ItemID = i.ItemID
JOIN supplier su ON su.SupplierID = Isnull(lastSupplier.supplierID, i.supplierID)
WHERE ss.WarehouseInvoiceNo = 10000000
--$P{invoiceNo}
You need to use OUTER APPLY here rather than LEFT JOIN:
OUTER APPLY (SELECT TOP 1 itemID
, supplierID
FROM SupplierInvoiceDetail sid
JOIN SupplierInvoice si ON si.SupplierInvoiceID = sid.SupplierInvoiceID
where (sid.ItemID = i.itemID) order by InvoiceDate desc
) AS lastSupplier
Subqueries introduced in FROM or JOIN clauses cannot refer to other table sources within the same FROM clause (effectively, they should all be evaluatable simultaneously). APPLY allows you to introduce a specific dependency in the evaluation.

Return Results Even If CTE Doesn't Resolve

I have a stored procedure on my SQL Server that consolidates a range of fields for use in SSRS for Report Builder. The procedure is fed a FileId and then works its logic. It works as intended until the File can't find or reference the Solicitor and Arresting Officer fields.
I need this to return a result even if the fileId does not have an Arresting Officer or Solicitor associated. I'm sure its something simple. Basically if the CTE returns nothing from the query, I still need a default row.
ALTER PROCEDURE [dbo].[GetRollCallData]
#Ids VARCHAR(255),
#LexiconId INT,
#UUID UNIQUEIDENTIFIER,
#ReadOnly INT
AS
DECLARE #TableCode INT
SET #TableCode = 58
IF #Ids <> ''
BEGIN
EXEC InsertInSelectionCache #Ids, #UUID, #TableCode, 0
IF #ReadOnly = 1
WITH DOACTE AS(
SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY CustomRecordsetId DESC) AS RowNumber, [File].*, FileType2Lexicon.Label as FileTypeLabel, [People].DefaultPhone, [People].InvertedName, CustomField.Name as FieldLabel, CustomFieldValue.Value as FieldValue
FROM FileType2Lexicon, SelectionCache, [People], [File]
INNER JOIN [CustomRecordSet]
ON [CustomRecordset].RecordId = [File].Id
INNER JOIN CustomFieldValue
ON [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
INNER JOIN [CustomField2Lexicon]
ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
INNER JOIN [CustomField]
ON CustomField.Id = CustomField2Lexicon.CustomFieldId
WHERE [File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [File].FileTypeId = FileType2Lexicon.FileTypeId
AND FileType2Lexicon.LexiconId = #LexiconId
AND [File].ClientIdString = [People].ClientIdString
AND CustomFieldValue.Value <> ''),
SolicitorCTE AS(
SELECT [People].Name AS SolicitorName, [File].Id
FROM SelectionCache, [File]
INNER JOIN [People2File]
ON [People2File].FileId = [File].Id
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
WHERE
[File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [Role2Lexicon].Label = 'Solicitor'),
ArrestingOfficerCTE AS(
SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY [People].InvertedName ASC) AS RowNumber, [People].Name AS ArrestingOfficerName, [People].CompanyName AS ArrestingOfficerCompany, [File].Id
FROM SelectionCache, [File]
INNER JOIN [People2File]
ON [People2File].FileId = [File].Id
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
WHERE
[File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [Role2Lexicon].Label = 'Arresting Officer'),
PivotCTE AS(
SELECT *
FROM
(Select Id, FieldLabel, FieldValue FROM DOACTE) AS Source
PIVOT(
MAX(FieldValue) FOR FieldLabel IN ([Date_Arrest], [Graphic_Client], [Ticket_1], [Ticket_2], [Ticket_3], [Ticket_4], [Ticket_5], [Charge_1], [Charge_2], [Charge_3], [Charge_4], [Charge_5])) as Pvt
)
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
INNER JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
INNER JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ArrestingOfficerCTE.RowNumber = 1
ELSE
DELETE SelectionCache
WHERE UUID = #UUID
AND TableCode = #TableCode
END
You can left join for optional results. I also needed to add a null check for the Arresting officer to the where caluse so that this didn't exclude records despite the left join.
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
LEFT JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
LEFT JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ( ArrestingOfficerCTE.RowNumber = 1 or ArrestingOfficerCTE.RowNumber is null )
Can you try:
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
into #Results
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
INNER JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
INNER JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ArrestingOfficerCTE.RowNumber = 1
if ((select cout(*) from #Results) = 0)
begin
insert into #Results
select
.......your default values......
end
select * from #Results
drop table #Results
This is pretty much liebs19's answer, so I upvoted his since he got there first. I think the answer comes down to LEFT JOINing where you're INNER. Since I rewrote your query so I could actually understand what was going on and I made some changes you may or may not want, so I'll leave it here in case it's useful.
Mine is more lines than yours partially because I format differently, partially because I'm using a temp table to do once what you do around 4 times. Thing about CTE's is that when you stack them like this you're likely to get some really gnarly performance. The CTE's act basically like an on-the-fly view, and their SQL pretty much gets repeated everywhere. I'm taking your limiting [File] and moving it into a temp table. Then I'm pivoting it into another one (since this further limits things based on RowNumber being 1. Then I just use this with the 2 CTE's at the end and into your final result.
Lastly, SELECT * ... is evil. I only use it when I'm poking around querying for something. Putting it into a sproc like this will cause you issues as the schema or CTE's or so on change. When you're making a sproc, name every column, it'll bite you much less in the future.
Here it is, feel free to ignore if you don't find it useful:
ALTER PROCEDURE [dbo].[GetRollCallData]
#Ids VARCHAR(255),
#LexiconId INT,
#UUID UNIQUEIDENTIFIER,
#ReadOnly INT
AS
BEGIN
DECLARE #TableCode INT = 58;
IF #Ids <> ''
BEGIN
EXEC InsertInSelectionCache #Ids, #UUID, #TableCode, 0
IF #ReadOnly = 1
BEGIN
SELECT
-- Add any other fully qualified columns. * is evil for sprocs. Only good for poking around in your own queries.
AllFiles.Id
INTO #SelectionFile
FROM
[File] AllFiles
INNER JOIN SelectionCache Cache
ON Cache.RecordId = AllFiles.Id
AND Cache.UUID = #UUID
AND Cache.TableCode = #TableCode -- this is the code for File table
WHERE
AllFiles.Id <> 0
;WITH DOACTE AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY CustomRecordsetId DESC) AS RowNumber
, SelectionFile.Id AS FileId
-- [Replace with any other columns that you selected from [File] at the top.]
, Lexicon.Label AS FileTypeLabel
, [People].DefaultPhone
, [People].InvertedName
, CustomField.Name AS FieldLabel
, CustomFieldValue.Value AS FieldValue
FROM
#SelectionFile SelectionFile
INNER JOIN FileType2Lexicon Lexicon
ON Lexicon.FileTypeId = SelectionFile.FileTypeId
AND Lexicon.LexiconId = #LexiconId
INNER JOIN [People]
ON [People].ClientIdString = SelectionFile.ClientIdString
INNER JOIN [CustomRecordSet]
ON [CustomRecordset].RecordId = SelectionFile.Id
INNER JOIN CustomFieldValue
ON [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
AND CustomFieldValue.Value <> ''
INNER JOIN [CustomField2Lexicon]
ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
INNER JOIN [CustomField]
ON CustomField.Id = CustomField2Lexicon.CustomFieldId
)
SELECT
Pvt.FileId
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, Pvt.[Date_Arrest]
, Pvt.[Graphic_Client]
, Pvt.[Ticket_1]
, Pvt.[Ticket_2]
, Pvt.[Ticket_3]
, Pvt.[Ticket_4]
, Pvt.[Ticket_5]
, Pvt.[Charge_1]
, Pvt.[Charge_2]
, Pvt.[Charge_3]
, Pvt.[Charge_4]
, Pvt.[Charge_5]
INTO #PivotedFile
FROM
(
SELECT
FileId
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, FieldLabel
, FieldValue
, FieldLabel AS PivotFieldLabel
, FieldValue AS PivotFieldValue
FROM
DOACTE
WHERE
RowNumber = 1
) AS Source
PIVOT
(
MAX(PivotFieldValue)
FOR PivotFieldLabel
IN
(
[Date_Arrest]
, [Graphic_Client]
, [Ticket_1]
, [Ticket_2]
, [Ticket_3]
, [Ticket_4]
, [Ticket_5]
, [Charge_1]
, [Charge_2]
, [Charge_3]
, [Charge_4]
, [Charge_5]
)
) as Pvt
;WITH SolicitorCTE AS
(
SELECT
[People].Name AS SolicitorName
, SelectedFiles.FileId
FROM
#PivotedFile SelectedFiles
INNER JOIN [People2File]
ON [People2File].FileId = SelectedFiles.FileId
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
AND [Role2Lexicon].Label = 'Solicitor'
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
)
, ArrestingOfficerCTE AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY [People].InvertedName ASC) AS RowNumber
, [People].Name AS ArrestingOfficerName
, [People].CompanyName AS ArrestingOfficerCompany
, SelectedFiles.FileId
FROM
#PivotedFile SelectedFiles
INNER JOIN [People2File]
ON [People2File].FileId = SelectedFiles.FileId
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
AND [Role2Lexicon].Label = 'Arresting Officer'
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
)
SELECT
SelectedFiles.Id
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL') AS ArrestingOfficerCompany
, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName
, SolicitorCTE.SolicitorName
, SelectedFiles.[Date_Arrest]
, dbo.GetImagebyId(SelectedFiles.[Graphic_Client]) as Photo
, SelectedFiles.[Ticket_1]
, SelectedFiles.[Ticket_2]
, SelectedFiles.[Ticket_3]
, SelectedFiles.[Ticket_4]
, SelectedFiles.[Ticket_5]
, SelectedFiles.[Charge_1]
, SelectedFiles.[Charge_2]
, SelectedFiles.[Charge_3]
, SelectedFiles.[Charge_4]
, SelectedFiles.[Charge_5]
FROM #PivotedFile SelectedFiles
LEFT JOIN SolicitorCTE
ON SelectedFiles.FileId = SolicitorCTE.FileId
LEFT JOIN ArrestingOfficerCTE
ON SelectedFiles.FileId = ArrestingOfficerCTE.FileId
AND ArrestingOfficerCTE.RowNumber = 1
DROP TABLE #SelectionFile
DROP TABLE #PivotedFile
END
ELSE
DELETE SelectionCache
WHERE
UUID = #UUID
AND TableCode = #TableCode
END
END
(If you do use it, read the -- [Replace...] comments.

Resources