How do I use a CASE statement in a JOIN in SQL Server? - sql

I have a stored procedure that I want to select a column if the applicationTypeId is in a list of IDs. I am trying to use the CASE statement but I don't know what I am doing wrong. I created a table and added the ApplicationTypeIds to it. The table name is #RelationshipsTypeApplicationId
In other words, what I am trying to do is the following:
If the applicationTypeId is in the #RelationshipsTypeApplicationId table
Join and select the Name column from the IGCRelationshipTypes table
Here is my original stored procedure
WITH AllCustomers AS
(
SELECT
app.ApplicationId,
cust.Name,
ApplicationTypes.TypeName AS ApplicationType,
ApplicationSources.ApplicationSourceName AS ApplicationSource,
CreatedDate = app.CreatedDate,
LastUpdateDate = app.StatusChangeDate,
app.StatusId,
InProgress = STUFF((SELECT ';'+#aw.ApplicationWorkflowName
FROM #aw
WHERE #aw.ApplicationId = app.ApplicationId
ORDER BY StepNumber
FOR XML PATH('')), 1, 1, ''),
ActionRequired = (SELECT top 1 1 FROM #aw
WHERE #aw.ApplicationId = app.ApplicationId
AND #aw.WorkflowStatusId = 6),
AccountId = STUFF((SELECT ';' + acct.AccountId
FROM #accounts AS acct
WHERE acct.ApplicationId = app.ApplicationId
ORDER BY acct.ParentAccountId
FOR XML PATH('')), 1, 1, '')
FROM
[dbo].[Applications] app
INNER JOIN
[dbo].[Customers] AS cust ON cust.CustomerId = app.CustomerId
INNER JOIN
[dbo].[ApplicationTypes] ON ApplicationTypes.ApplicationTypeId = app.ApplicationTypeId
INNER JOIN
[dbo].[ApplicationSources] ON ApplicationSources.ApplicationSourceId = app.ApplicationSourceId
WHERE
app.StatusId <> '4020-8901-64FFE33F06B1'
AND (#applicationTypeId IS NULL OR app.ApplicationTypeId = #applicationTypeId)
And here is what I updated:
WITH AllCustomers AS
(
SELECT
app.ApplicationId,
cust.Name,
ApplicationTypes.TypeName AS ApplicationType,
ApplicationSources.ApplicationSourceName AS ApplicationSource,
CreatedDate = app.CreatedDate,
LastUpdateDate = app.StatusChangeDate,
app.StatusId,
InProgress = STUFF((SELECT ';' + #aw.ApplicationWorkflowName
FROM #aw
WHERE #aw.ApplicationId = app.ApplicationId
ORDER BY StepNumber
FOR XML PATH('')), 1, 1, ''),
ActionRequired = (SELECT top 1 1 FROM #aw
WHERE #aw.ApplicationId = app.ApplicationId
AND #aw.WorkflowStatusId = 6),
AccountId = STUFF((SELECT ';' + acct.AccountId
FROM #accounts as acct
WHERE acct.ApplicationId = app.ApplicationId
ORDER BY acct.ParentAccountId
FOR XML PATH('')), 1, 1, ''),
CASE
WHEN app.ApplicationTypeId IN (SELECT * FROM #RelationshipsTypeApplicationId)
THEN relationshipType.Name
END
FROM
[dbo].[Applications] app
INNER JOIN
[dbo].[Customers] AS cust ON cust.CustomerId = app.CustomerId
INNER JOIN
[dbo].[ApplicationTypes] ON ApplicationTypes.ApplicationTypeId = app.ApplicationTypeId
INNER JOIN
[dbo].[ApplicationSources] ON ApplicationSources.ApplicationSourceId = app.ApplicationSourceId
INNER JOIN
[dbo].[IGCRelationshipTypes] AS relationshipType
ON CASE
WHEN app.ApplicationTypeId IN (SELECT * FROM #RelationshipsTypeApplicationId)
THEN (relationshipType.Name = #relationshipType)
END
WHERE
app.StatusId <> '4020-8901-64FFE33F06B1'
AND (#applicationTypeId IS NULL OR app.ApplicationTypeId = #applicationTypeId)
Here is a screenshot of the syntax error:
Can someone shed some light on what I am missing here?

CASE in T-SQL is an expression that returns a single scalar value, it is not for control of flow. See Dirty secrets of the CASE expression. You'll need something like this, but I don't have the energy to try to determine why you have a table named #RelationshipsTypeApplicationId with a single column (because you really shouldn't say IN (SELECT *)) or if you want to do something different when the match does not exist.
...
ON relationshipType.Name = CASE
WHEN app.ApplicationTypeId IN
(SELECT * FROM #RelationshipsTypeApplicationId)
THEN #relationshipType END
...

Related

Use 'Stuff' variable in WHERE clause

So here is the query code we are using:
SELECT
CONVERT(DATE, Nominations.Nomination_Date_Created) AS Nomination_Date_Created,
Nominations.Nomination_Status,
(CASE
WHEN MIN(EPORT.dbo.FDA_Divisions.division_name) = MAX(EPORT.dbo.FDA_Divisions.division_name)
THEN MIN(EPORT.dbo.FDA_Divisions.division_name)
ELSE 'Multiple Divisions'
END) AS Employee_Division,
Nominations.Nomination_Awarded_For,
Nominations.Nomination_Awarded_Other,
Nom.First_Name + ' ' + Nom.Last_Name AS Nominator_Name,
Nominations.Nomination_Group_UUID,
Nominations.Nomination_Group_Name,
Nominations.Nomination_Group_Time_off_Sum,
Nominations.Nomination_Group_Cash_Sum,
Nominations.Nomination_Type,
Nominations.Nomination_Identifier, Nominations.Nomination_Employee_UUID,
Nominations.Nomination_Nominator_ID, Nominations.Nomination_NOAC,
STUFF((SELECT ', ' + NOMGroup.division_name
FROM vw_group_nomination_divisions NOMGroup
WHERE NOMGroup.Nomination_Group_UUID = Nominations.Nomination_Group_UUID
FOR XML PATH('')), 1, 1, '') divList
FROM
Nominations
INNER JOIN
ePort.dbo.Employees AS Employees_1 ON Employees_1.CapHR_ID = Nominations.Nomination_Employee_CapHR_ID
LEFT OUTER JOIN
ePort.dbo.FDA_Offices ON Employees_1.office_id = ePort.dbo.FDA_Offices.office_id
LEFT OUTER JOIN
ePort.dbo.FDA_Centers ON Employees_1.center_ID = ePort.dbo.FDA_Centers.Center_ID
LEFT OUTER JOIN
ePort.dbo.FDA_Divisions ON Employees_1.division_id = ePort.dbo.FDA_Divisions.division_ID
LEFT OUTER JOIN
ePort.dbo.Employees AS Nom ON Nominations.Nomination_Nominator_ID = Nom.CapHR_ID
LEFT OUTER JOIN
ePort.dbo.Employees AS NomAppRTO ON Nominations.Nomination_Approving_Officer_NED_ID = NomAppRTO.CapHR_ID
GROUP BY
CONVERT(DATE, Nominations.Nomination_Date_Created),
Nominations.Nomination_Awarded_For, Nominations.Nomination_Status,
Nominations.Nomination_Awarded_Other,
Nom.First_Name + ' ' + Nom.Last_Name,
Nominations.Nomination_Type, Nominations.Nomination_Group_UUID,
Nominations.Nomination_Group_Name,
Nominations.Nomination_Group_Time_off_Sum,
Nominations.Nomination_Group_Cash_Sum,
Nominations.Nomination_Identifier, Nominations.Nomination_Type,
Nominations.Nomination_Employee_UUID,
Nominations.Nomination_Nominator_ID, Nominations.Nomination_NOAC
HAVING
(Nominations.Nomination_Type = 'Group')
AND (YEAR(CONVERT(DATE, Nominations.Nomination_Date_Created)) IN ('2020'))
ORDER BY
Nomination_Date_Created DESC, Nominations.Nomination_Group_UUID
Output:
| Id | divList |
+--------------------------------------+-------------------+
| 3462BF9B-5056-9C58-994BFFC6A38E7368 | DLR, DTD, OHCM |
| 3B8202C2-5056-9C58-99C591AA86B3A1C9 | OHCM |
| CB5A722C-5056-9C58-9983C1F6C66C0AD7 | DTD, STMD |
And the output is how we need it, however, we need to be able to search it and we cannot get that working. So how does one reference the column 'Name' that the Stuff function creates in the WHERE clause of the query?
We need to do a search within the HAVING OR WHERE clause for a value within the 'divList' column if possible. Such as divList IN ('OHCM').
Anytime I reference 'divList', I get the error:
Invalid column name 'divList'.
This would filter the results to records 1 and 2.
I hope that better explains it.
You don't want the string. Use more basic logic instead:
having sum(case when division_name = 'ccc' then 1 else 0 end) > 0
How is your temp table associated with the view. You need to join your temp table with the nominations view.
SELECT ID,
STUFF((SELECT ', ' + NOMGroup.division_name
FROM vw_group_nomination_divisions NOMGroup
WHERE NOMGroup.Nomination_Group_UUID = nom.Nomination_Group_UUID
FOR XML PATH('')), 1, 1, '') Name
FROM temp1
JOIN vw_group_nomination_divisions nom ON temp1.ID = nom.ID
WHERE Nominations.[Name] = 'ccc'
GROUP by ID

Attempting to set a non-NULL- able column's value to NULL

I am getting attempting to set a non-NULL- able column's value to NULL
error when I use FOR XML PATH('')
Code:
select
fdp.POLICYNUMBER,
fdp.INSUREDNAME,
fdp.OWNERNAME,
fdp.AGENCYCODE,
p.WFWORKSTEPNAME,
fdpc.NIGO,
fdpc.NIGOREASON,
d.NIGOREQUIREMENT,
wci.WCSTATUS,
wci.DATECOMPLETED,
fdCI.NEWUNDERWRITINGUSER,
fdr.NBAMOUNT
into
#t
from
PINewBusiness p
join
FDPolicyDetails fdp on SUBSTRING(p.CFREPKEY, 9, LEN(p.CFREPKEY)) = fdp.PARENT_CASEID
and (p.WFWORKSTEPNAME = 'PendingRequirements' or
p.WFWORKSTEPNAME = 'FollowUpRequirements' )
join
FDProcessing fdpc on SUBSTRING(p.CFREPKEY, 9, LEN(p.CFREPKEY)) = fdpc.PARENT_CASEID
join
FDRounting fdr on SUBSTRING(p.CFREPKEY, 9, LEN(p.CFREPKEY)) = fdr.PARENT_CASEID
cross apply
(select NIGOREQUIREMENT + ', '
from FDNIGORequirements nr
where nr.PARENT_CASEID = fdpc.PARENT_CASEID
for xml path('')) D (NIGOREQUIREMENT)
--join FDNIGORequirements nr on SUBSTRING(p.CFREPKEY, 9, LEN(p.CFREPKEY)) = nr.PARENT_CASEID
cross apply
(select NIGOREQUIREMENT + ', '
from FDNIGORequirements nr
where nr.PARENT_CASEID = SUBSTRING(p.CFREPKEY,9,LEN(p.CFREPKEY))
for xml path('')) D (NIGOREQUIREMENT)
join
(select max(CREATEDDATETIME) as CREATEDDATETIME, PARENT_CASEID
from FDWelcomeCall
group by PARENT_CASEID ) wc on fdr.PARENT_CASEID = wc.PARENT_CASEID
join
FDWelcomeCall wci on wci.PARENT_CASEID = wc.PARENT_CASEID
and wci.CREATEDDATETIME = wc.CREATEDDATETIME
join
FDCaseInformation fdCI on SUBSTRING(p.CFREPKEY, 9, LEN(p.CFREPKEY)) = fdCI.PARENT_CASEID
where
p.WFSTEPENTRYTIME >= #sdate
and p.WFSTEPENTRYTIME <= #edate
order by
p.WFFLOWENTRYTIME desc
If you want to keep the rows with NULL values you must replace the nulls in the column that gives you the error, to do so you can use:
SELECT COALESCE([MyColumn],__ReplacementValue__) AS [MyColumn] FROM MyTable
or
SELECT ISNULL([MyColumn],__ReplacementValue__) AS [MyColumn] FROM MyTable
You can use one of them in the inner or outer SELECT.
Otherwise, if the row should not exist if that value is null you must filter it out by adding a WHERE clause:
WHERE [MyColumn] IS NOT NULL

Data show by list when group by is not include data

I have a sql command like this
select mainPOID.EstAPDate,mainPOID.POID,TTm.ID,TTMAmount=TTMD.InvoiceAmount
From TTBeforeMms TTM
inner join TTBeforeMms_Detail TTMD on TTM.ID = TTMD.ID
inner join (
select distinct main.EstAPDate,main_D.POID
From AP main
left join AP_Detail main_D on main.ID = main_D.ID
where main.Type ='PA' and main.EstAPDate between '2018/6/01' AND '2018/6/15' and left(main_D.InvoiceNo,4) != '1111' ) mainPOID on TTMD.poid =mainPOID.POID and TTM.EstAPdate<=mainPOID.EstAPdate and mainPOID.POID='CM3PU18030009'
order by mainPOID.EstAPDate,mainPOID.POID
sql result will like this
My question is
How can Data show by list when group by is not include data?
For example
ID will show by list When I group by EstAPDate、POID and sum(TTMAmount)
You can store in one temp table or use CTE
CREATE TABLE [dbo].#Columnss(
espapdate date ,
poid varchar(max),
id varchar(max),amount decimal(22,6))
GO
insert into #Columnss values('2018-06-15','cm3','pt20',19988.8900)
insert into #Columnss values('2018-06-15','cm3','pt21',265.8900)
SELECT
REPLACE(ESPAPDATE,'-','/') ESPAPDATE, POID,
STUFF(
(SELECT ' , ' + OD.ID
FROM #COLUMNSS OD
WHERE OD.ESPAPDATE = O.ESPAPDATE
AND OD.POID = O.POID
FOR XML PATH('')), 1, 2, ''
) PRODUCTNAMES,SUM(AMOUNT)AMOUNT
FROM #COLUMNSS O
GROUP BY ESPAPDATE, POID
output
espapdate poid ProductNames amount
2018/06/15 cm3 pt20 , pt21 20254.780000
there are lots of CSV example using FOR XML PATH. For your case here, i am wrapping your existing query in a CTE and then from there generate the CSV string for ID
; with
cte as
(
select mainPOID.EstAPDate, mainPOID.POID, TTm.ID, TTMAmount=TTMD.InvoiceAmount
From TTBeforeMms TTM
inner join TTBeforeMms_Detail TTMD on TTM.ID = TTMD.ID
inner join (
select distinct main.EstAPDate,main_D.POID
From AP main
left join AP_Detail main_D on main.ID = main_D.ID
where main.Type ='PA'
and main.EstAPDate between '2018/6/01' AND '2018/6/15'
and left(main_D.InvoiceNo,4) != '1111'
) mainPOID on TTMD.poid = mainPOID.POID
and TTM.EstAPdate <= mainPOID.EstAPdate
and mainPOID.POID = 'CM3PU18030009'
)
SELECT EstAPDate, POID,
ID = STUFF(c.ID, 1, 1, ''),
TTMAmount = SUM(TTMAmount)
FROM cte
CROSS APPLY
(
SELECT ',' + ID
FROM cte x
WHERE x.EstAPDate = cte.EstAPDate
AND x.POID = cte.POID
FOR XML PATH ('')
) c (ID)
GROUP BY EstAPDate, POID
ORDER BY EstAPDate, POID

SQL server Stuff on multiple columns

I want to concatenate the value of multiple columns for the same ID.
I managed to concatenate for the first column, but when trying the same syntax for the second I'm having an error "The multi-part identifier EnqAct.[ActionID] could not be bound."
Example_Data_Result
Here I managed to group several MachineName together, as seen in "Column1" but I can't manage to group both the MachineName and Description in their own column
My working Query :
SELECT Enq.[EnquiryID],
Enq.[CustomerName],
DetPrio.[Description],
Stuff((SELECT ', ' + Mach.[MachineName]
FROM [dbo].[Machine] Mach
INNER JOIN [dbo].[MachineEnquiry] MachEnq
ON Mach.[MachineID] = MachEnq.[MachineID]
WHERE Enq.[EnquiryID] = MachEnq.[EnquiryID]
FOR XML PATH('')), 1, 2, ''),
DetAct.[Description]
FROM [dbo].[Enquiry] Enq
INNER JOIN [dbo].[EnquiryAction] EnqAct
ON EnqAct.[EnquiryID] = Enq.[EnquiryID]
INNER JOIN [dbo].[DetailsAction] DetAct
ON DetAct.[ActionID] = EnqAct.[ActionID]
INNER JOIN [dbo].[DetailsPriority] DetPrio
ON DetPrio.[PriorityID] = Enq.[Priority]
GROUP BY Enq.[EnquiryID],
Enq.[CustomerName],
DetPrio.[Description],
DetAct.[Description]
My non working Query :
SELECT Enq.[EnquiryID],
Enq.[CustomerName],
DetPrio.[Description],
Stuff((SELECT ', ' + Mach.[MachineName]
FROM [dbo].[Machine] Mach
INNER JOIN [dbo].[MachineEnquiry] MachEnq
ON Mach.[MachineID] = MachEnq.[MachineID]
WHERE Enq.[EnquiryID] = MachEnq.[EnquiryID]
FOR XML PATH('')), 1, 2, ''),
Stuff((SELECT ', ' + DetAct.[Description]
FROM [dbo].[DetailsAction] DetAct
INNER JOIN [dbo].[EnquiryAction] EnqAct
ON EnqAct.[ActionID] = DetAtc.[ActionID]
WHERE Enq.[EnquiryID] = EnqAct.[EnquiryID]
FOR XML PATH('')), 1, 2, '')
FROM [dbo].[Enquiry] Enq
INNER JOIN [dbo].[DetailsPriority] DetPrio
ON DetPrio.[PriorityID] = Enq.[Priority]
GROUP BY Enq.[EnquiryID],
Enq.[CustomerName],
DetPrio.[Description]
Both work the same way, I have a table Enquiry which will have an EnquiryID.
then in my table EnquiryAction or MachineEnquiry I will have entitys with an EnquiryID and an Action/Machine ID
Then in my DetailsAction/Machine Table I will have the Action/Machine ID, and the string I want to get and concatenate.
Why am I having an error and is it possible to achieve what I'm trying to do ?

Parsing error when creating view

I have a view which takes multiple rows and Comma Separated Values (CSV) from table columns with data.
It was working well and I got the results that I needed. Now the view has some parsing error like:
Error in WHERE clause near '('. Unable to parse query text.
Can someone help? Here is my code:
SELECT dbo.table1.title,
Stuff((SELECT ', ' + CONVERT(NVARCHAR(4000), dbo.table3.uid) AS [text()]
FROM dbo.table2
INNER JOIN dbo.table3
ON dbo.table3.uid = dbo.table2.FK_Group
WHERE dbo.table3.uid = dbo.table2.FK_Group
AND dbo.table3.company = dbo.main.company
AND dbo.table2.FK_Version = dbo.table1.fk_Version
AND dbo.main_version.uid = dbo.table1.fk_Version
FOR XML PATH('')), 1, 1, '') AS groupName
FROM dbo.main_version
INNER JOIN dbo.[main]
ON dbo.version.fk_main = dbo.[main].uid
INNER JOIN dbo.main_schema
ON dbo.[main].fk_SCHEMA = dbo.main_schema.uid
INNER JOIN dbo.table1
ON dbo.version.uid = dbo.table1.fk_Version
WHERE ( dbo.main_version.active = 1 )