Insert values to a table from another table based on condition - sql

So I have a SQL table in which I am entering values by joining other columns and entering the column values from that table.
CREATE TABLE #temp_t (id INT, cname NVARCHAR(100), val INT, aid INT)
INSERT INTO #temp_t
SELECT DISTINCT
ISNULL(IDXC.id, 0) id, sg.name + '-webApp' cName, 0 val, ag.ID aid
FROM spgroup sg
JOIN APPA APP ON sg.id > 1 AND sg.val & 4 = 0 AND APP.dagi = sg.id
JOIN AIDBI XDI ON APP.bs = XDI.bsid
LEFT JOIN #IDXC ON IDXC.agpv = sg.id
WHERE IDXC.id IS NULL
Now while inserting values to the table I need to check if sg.name exists in sysName table if yes then -webApp needs to be replaced by -andApp otherwise it remains -webApp
How can I do the same?

You can use EXISTS in a CASE expression:
SELECT DISTINCT COALESCE(i.id, 0) as id,
(sg.name +
(CASE WHEN EXISTS (SELECT 1 FROM sysname sn WHERE sn.name = sg.name)
THEN '-andApp' ELSE '-webApp'
END)
) as cName,
0 as val, ag.ID as aid
FROM spgroup sg JOIN
APPA APP
ON sg.id > 1 AND (sg.val & 4) = 0 AND APP.dagi = sg.id JOIN
AIDBI XDI
ON APP.bs = XDI.bsid LEFT JOIN
#IDXC i
ON i.IDXCsgpv = sg.id
WHERE i.id IS NULL

Related

How to prioritize a record In sql server?

I want to try to write a query. I need to take the Targetvalue from #MetricTargets table for the MetricID's which are there in #Metrics.
{
CREATE TABLE #Metrics(
MetricId BiginT,
AccountId Bigint,
CountryId Bigint
)
INSERT INTO #Metrics(MetricId,AccountId,CountryId)select 8253,3,105
Create table #MetricTargets(
AccountId BIGINT,
MetricId BIGINT,
TargetValue BIGINT,
Countryid BIGINT
)
INSERT INTO #MetricTargets(AccountId,TargetValue,MetricId,Countryid)SELECT 105,100,3,8253
INSERT INTO #MetricTargets(AccountId,TargetValue,MetricId,Countryid)SELECT -1,80,3,8253
INSERT INTO #MetricTargets(AccountId,TargetValue,MetricId,Countryid)SELECT 105,99,-1,8253
}
CountryId=-1 and AccountId =-1 represents for all Countries and Accounts
So I want to retrieve Targetvalue for a metricId if the AccountId and CountryId is given in #MetricTargets table in first Priority , AccountId =Something and countryId = -1 is 2 nd priority,ACcountId=-1 and CountryId= SomeThing then 3rd priority and AccountId =-1 and CountryId=-1 then last priority.
I wrote the below query but it is giving all records.
select M.TargetValue from #Metrics S
LEFT JOIN #MetricsTargets M
ON M.MetricId = S.MetricId AND (S.AccountId+M.AccountId<S.AccountId or S.AccountId = M.AccountId)
AND (S.CountryId+M.CountryId<S.CountryId or S.CountryId=M.CountryId)
You seem to want matching with -1 as a wildcard of lower priority. I'm pretty sure a lateral join does what you want:
select . . .
from #Metrics m OUTER APPLY
(select top (1) mt.*
from #MetricsTargets mt
where mt.MetricId = m.MetricId and
m.account_id in (mt.account_id, -1) and
m.country_id in (mt.country_id, -1)
order by (case when mt.account_id = m.account_id and mt.country_id = m.country_id
then 1
when mt.account_id = m.account_id and mt.country_id = -1
then 2
when mt.account_id = -1 and mt.country_id = m.country_id
then 3
when mt.account_id = -1 and mt.country_id = -1
then 4
end)
) mt

SQL Server add a score if an answer is the same as the correct answer with group by clause

I have this code and its temporary tables so you can run it.
create table #student(
id int identity(1,1),
name varchar(50)
)
create table #quiz(
id int identity(1,1),
name varchar(50),
points_worth int
)
create table #exam(
id int identity(1,1),
sequence int,
question varchar(50),
answer varchar(50),
quiz_id int
)
create table #student_taken(
id int identity(1,1),
sequence int,
answer varchar(50),
student_id int,
quiz_id int
)
insert into #student(name)
values('Uzumaki Naruto'),('Uchiha Sasuke'),('Haruno Sakura')
insert into #quiz(name,points_worth)
values('Chunin Exam',2)
insert into #exam(sequence,question,answer,quiz_id)
values(1,'Hinata and Neji are siblings','True',1),
(2,'Uchiha Sasuke is part of the Akatsuki','False',1),
(3,'Tsunade and Jiraiya has a son','False',1)
insert into #student_taken(sequence,answer,quiz_id,student_id)
values(1,'True',1,1),(2,'True',1,1),(3,'True',1,1),(1,'True',1,2),(2,'False',1,2),(3,'False',1,2),
(1,'True',1,3),(2,'False',1,3),(3,'False',1,3)
drop table #student
drop table #exam
drop table #quiz
drop table #student_taken
So as you can see I Uzumaki Naruto only has 1 point, cause he only got 1 correct answer, and both Sakura and Sasuke has 3 points each.
Now I want it to be like this:
id name score
1 Uzumaki Naruto 2
2 Uchiha Sasuke 6
3 Haruno Sakura 6
He got 6 because in my #quiz table i added points worth(it is points worth for each number of items).
So now I was wondering if group by clause is needed to this? and what is the correct summation, I want that if True = True then it adds 1 point and False = False same and False = True will not count.
Here is my attempt
select
ST.student_id,
SUM(1 * Q.points_worth) 'sum'
from #student_taken ST
inner join #exam E
on E.quiz_id = ST.quiz_id
inner join #quiz Q
on Q.id = E.quiz_id
group by ST.student_id
I'm not really sure what your question is here. #JorgeCampos isn't quite correct, in that a GROUP BY is only required if you are returning aggragated and non-aggrated fields in the same dataset (without the use of a OVER clause).
As for getting the result set, I'm not quite sure how you came to the conclusion you did. The value of points_worth is in your quiz table, not the exam table, so I assume every question has the same value for that quiz? If so, this is one idea for your query:
SELECT q.[name] AS QuizName,
s.[name] As StudentName,
COUNT(CASE WHEN st.answer = e.answer THEN 1 END) * q.points_worth AS Score,
COUNT(CASE WHEN st.answer = e.answer THEN 1 END) AS Correct,
COUNT(CASE WHEN st.answer != e.answer THEN 1 END) AS Incorrect
FROM #student s
JOIN #student_taken st ON s.id = st.student_id
JOIN #exam e ON st.[sequence] = e.id
JOIN #quiz q ON e.quiz_id = q.id
GROUP BY q.[name], s.[name],
q.points_worth;
We could however, go a little further and see if a Student actually answered all the questions (and exclude those that answered none), thus we get:
INSERT INTO #quiz([name],points_worth)
VALUES('Basic Maths',1);
INSERT INTO #exam([sequence],question,answer,quiz_id)
VALUES(1,'5 + 2 * 3 = 21','False',2),
(2,'9 - 1 * 2 = 7','True',2);
INSERT INTO #student ([name])
VALUES ('Jane Smith'),('Sally Bloggs');
INSERT INTO #student_taken ([sequence],answer,quiz_id,student_id)
VALUES (1, 'false', 1, 4),
(1, 'false', 2, 4),
(2, 'true', 2, 4),
(1, 'true', 2, 5);
GO
SELECT q.[name] AS QuizName,
s.[name] As StudentName,
COUNT(CASE WHEN st.answer = e.answer THEN 1 END) * q.points_worth AS Score,
COUNT(CASE WHEN st.answer = e.answer THEN 1 END) AS Correct,
COUNT(CASE WHEN st.answer != e.answer THEN 1 END) AS Incorrect,
COUNT(CASE WHEN st.answer IS NULL THEN 1 END) AS Unanswered
FROM #quiz q
JOIN #exam e ON q.id = e.quiz_id
CROSS JOIN #student s
LEFT JOIN #student_taken st ON s.id = st.student_id
AND e.[sequence] = st.[sequence]
AND q.id = st.quiz_id
WHERE EXISTS (SELECT 1 FROM #student_taken sq WHERE sq.student_id = s.id AND sq.quiz_id = q.id)
GROUP BY q.[name], s.[name],
q.points_worth;
Hope that helps.
You can try this method: find how many correct points / student (query inside of CTE) and then take result and join the #quiz table to calculate the final points by applying the points_worth
;with cte as (
select
st.student_id
,st.quiz_id
,COUNT(e.id) as points
from #student_taken st
left join #exam e
on st.quiz_id = e.quiz_id
and st.answer = e.answer
and st.sequence = e.sequence
group by st.student_id, st.quiz_id
) select
student_id
,s.name
--,quiz_id
,points * q.points_worth
from cte
inner join #quiz q
on quiz_id = q.id
inner join #student s
on student_id = s.id
Add a conditional inside the sum. I also noticed the join to from #student_taken to #exam wasn't working correctly because you're only joining on quiz_id, while you also need to join on sequence.
So here's your attempt with those modifications:
select
ST.student_id,
SUM(IIF(ST.answer = E.answer, Q.points_worth, 0)) 'sum'
from #student_taken ST
inner join #exam E
on E.quiz_id = ST.quiz_id and ST.sequence = E.sequence
inner join #quiz Q
on Q.id = st.quiz_id
group by ST.student_id
The IIF function evaluates the first parameter as a conditional, returns the second parameter if true, and the third parameter if false. So if the student answered what the exam expects (ST.answer = E.answer), it returns the points worth, otherwise 0.
If you'd rather not use IIF, you can use a case statement: case when ST.answer = E.answer then Q.points_worth else 0 end. I personally just think IIF looks cleaner, and SQL Server Management Studio goes a bit crazy with syntax hinting if you mess up a case statement.

TSQL not pulling in complete data set

I have a complicated stored procedure that worked great until the client wanted to change it.
I am not great with complicated TSQL so I have no idea what is wrong with my code.
Here is the situation. I have three temp tables, Cost, Adjustments, and Payments.
In the end I merge all these tables together in a report table. The problem I am having is even if one or even two of these tables are null, as long as one table has data I need that data to show. I currently have it set up with full outer joins but I'm still not getting the full list, I'm missing probably....50 ish records that should be there.
Can anyone look at this code and tell me what the heck I'm doing wrong? I'm bringing all the data together on #ThisReportAll
UPDATE: So I removed the having clause to see what was going on, and the data for the overdue balance is returning null. So the math isn't...mathing correctly, any ideas?
CODE
CREATE TABLE #BalanceAdjustmentsAll (CustomerId int, Amount decimal(20,2));
CREATE TABLE #AnimalCostsAll (thisIndex int IDENTITY(1,1), AnimalTypeId int, Cost decimal(20,2));
CREATE TABLE #TotalAnimalCostAll (thisIndex int IDENTITY(1,1), YearSetupId int, AnimalTypeId int, AnimalType varchar(max), OwnerId int, CustomerId int, AnimalCount int, TtlSpeciesCost decimal(20,2));
CREATE TABLE #CustomerPaymentsAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), TtlPayments decimal(20,2));
CREATE TABLE #CustomerInfoAll (thisIndex int IDENTITY(1,1), OwnerId int, CustomerId int, FName nvarchar(200), LName nvarchar(200),BName nvarchar(200));
CREATE TABLE #ThisReportAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), Year char(4), OverdueBalance decimal(20,2), YearSetupId int);
INSERT INTO #BalanceAdjustmentsAll (CustomerId, Amount)
SELECT CustomerId, SUM(Amount)
FROM BalanceAdjustment
WHERE YearSetupId = 3
GROUP BY CustomerId;
/* GET Costs per Animal for 'This' yearID */
INSERT INTO #AnimalCostsAll (AnimalTypeId, Cost)
SELECT AnimalTypeId, Cost
FROM PerCapitaFee
WHERE YearSetupId = 3;
/* GET animal type totals for owner per year */
INSERT INTO #TotalAnimalCostAll (yearSetupId,AnimalTypeId,AnimalType,OwnerId,CustomerId,AnimalCount,TtlSpeciesCost)
SELECT YearSetup.YearSetupId,AnimalCount.AnimalTypeId,AnimalType.ShortDescription,Owner.OwnerId,Report.CustomerId,AnimalCount.Count,(ac.Cost * AnimalCount.Count)
FROM AnimalCount
INNER JOIN #AnimalCostsAll as ac
ON ac.AnimalTypeId = AnimalCount.AnimalTypeId
INNER JOIN AnimalType
ON AnimalCount.AnimalTypeId=AnimalType.AnimalTypeId
INNER JOIN AnimalLocation
ON AnimalLocation.AnimalLocationid=AnimalCount.AnimalLocationId
INNER JOIN Owner
ON Owner.OwnerId=AnimalLocation.OwnerId
AND Owner.OwnerType = 'P'
INNER JOIN Report
ON Report.ReportId=Owner.ReportId
INNER JOIN YearSetup
ON Report.YearSetupId=YearSetup.YearSetupId
INNER JOIN County
ON County.CountyId=AnimalLocation.CountyId
WHERE YearSetup.YearSetupId = 3 AND Report.Completed IS NOT NULL AND Report.CustomerId IS NOT NULL
/* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b ON bp.BatchId=b.BatchId
WHERE BPS.CustomerId IS NOT NULL
AND
(
((b.BatchTypeId = 'M' OR b.BatchTypeId = 'C' OR b.BatchTypeId = 'E') AND (b.BatchStatusId = 'S'))
OR
((b.BatchTypeId = 'B' OR b.BatchTypeId = 'N' OR b.BatchTypeId = 'R' OR b.BatchTypeId = 'T') AND (b.BatchStatusId = 'S' OR b.BatchStatusId='C'))
)
AND
BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
/* Deal with the name/id stuff */
INSERT INTO #CustomerInfoAll(FName, LName, BName, OwnerId, CustomerId)
SELECT
o.FirstName AS FName,
o.LastName AS LName,
o.BusinessName AS BName,
o.OwnerId AS OwnerId,
r.CustomerId AS CustomerId
FROM Owner o
INNER JOIN Report r
ON o.ReportId = r.ReportId
AND o.OwnerType = 'P'
WHERE r.CustomerId IN (SELECT CustomerId FROM #TotalAnimalCostAll)
AND r.Completed IS NOT NULL
AND r.YearSetupId = 3
AND NOT EXISTS(
SELECT 1 FROM Report
WHERE r.CustomerId = Report.CustomerId
AND Report.Completed IS NOT NULL
AND r.ReportId != Report.ReportId
AND r.YearSetupId = Report.YearSetupId
AND (
r.Completed < Report.Completed
OR (
r.Completed = Report.Completed
AND r.ReportId < Report.ReportId
)
)
)
ORDER BY CustomerId;
/** MAKE IT SO #1 **************************************************/
/* Simply Joining The Customer Info to the calculated totals to avoid any aggregation shenanigans... */
INSERT INTO #ThisReportAll (CustomerID,Year,OverdueBalance,YearSetupId)
SELECT COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID), ys.Name AS Year,
CASE
WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN (5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END
AS TtlOwnerCost, t.YearSetupId AS YearSetupId
FROM #TotalAnimalCostAll t
FULL OUTER JOIN #CustomerPaymentsAll cp ON t.CustomerId=cp.CustomerID
FULL OUTER JOIN #BalanceAdjustmentsAll ba ON COALESCE(t.CustomerId,cp.CustomerId)=ba.CustomerID
LEFT JOIN YearSetup ys ON COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID) = ys.YearSetupId
GROUP BY COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID),ys.Name,cp.TtlPayments, ba.Amount, t.YearSetupId
HAVING
CASE WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN SUM(5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END < 0;
/* Return some meaningful report data */
SELECT r.Year AS [YearName],r.CustomerID,left(ci.FName,20) AS [FirstName], left(ci.LName,40) AS [LastName], left(ci.BName,40) AS [BusinessName],r.OverdueBalance AS [Balance],r.YearSetupId
FROM #ThisReportAll r
LEFT JOIN #CustomerInfoAll ci ON r.CustomerID = ci.CustomerId
ORDER BY CAST(r.CustomerID as int) ASC;
DROP TABLE #BalanceAdjustmentsAll;
DROP TABLE #AnimalCostsAll;
DROP TABLE #TotalAnimalCostAll;
DROP TABLE #CustomerPaymentsAll;
DROP TABLE #CustomerInfoAll;
DROP TABLE #ThisReportAll;
Found it. I didn't have a default value for t.TtlSpeciesCost if it was null
SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
to
SUM(ISNULL(t.TtlSpeciesCost,0)) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
Some missing records may be found here:
by adjusting /* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp
ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b
ON bp.BatchId=b.BatchId
AND ((b.BatchTypeId IN ('M', 'C', 'E') AND b.BatchStatusId = 'S')
OR (b.BatchTypeId IN ('B','N','R','T') AND (b.BatchStatusId IN ('S','C')))
WHERE BPS.CustomerId IS NOT NULL
AND BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
The WHERE on B would have negated the left join causing null records to be omitted. or made the left join to behave like an inner join.
To know for certain we need sample data from your tables showing which records are being omitted that you need to retain.
I also refactored the OR's and made them "IN"s to improve readability.

SQL join to always return initial match and NULLs for subsequent mismatches

How can a join be created that will always return a row for those units in Unit that have a row in Test even when the row in test is in TestDetail with a PartID that has a row in Part with a PartFamilyID that has a row in PartFamily with a Name not equal to, in this case, B. In other words, always return a record for those units with a test record but with NULL values when the subsequent joins are false.
For example, from the code below I expected (I apologize I do not have the reputation to post images and I cannot figure out a way to post a table):
u.ID t.IDt.UnitID td.ID td.TestID td.PartID p.ID p.PartFamilyID pf.ID pf.Name
1 NULL NULL NULL NULL NULL NULL NULL NULL NULL
2 NULL NULL NULL NULL NULL NULL NULL NULL NULL
2 15 2 114 15 1115 1115 11115 11115 E
3 NULL NULL NULL NULL NULL NULL NULL NULL NULL
4 14 4 113 14 1112 1112 11114 11114 D
4 16 4 115 16 1114 1114 11115 11115 E
5 NULL NULL NULL NULL NULL NULL NULL NULL NULL
declare #Results table (UnitID int, Value varchar(10))
insert into #Results (UnitID)
values (1),(2),(3),(4),(5)
declare #Unit table (ID int)
insert into #Unit
values (1),(2),(3),(4),(5),(6),(7)
declare #Test table (ID int, UnitID int)
insert into #Test
values (11,1),(12,1),(13,2),(14,4),(15,2),(16,4)
declare #TestDetail table (ID int, TestID int, PartID int)
insert into #TestDetail
values (111,11,1111),(112,13,1111),(113,14,1112),(114,15,1115),(115,16,1114)
declare #Part table (ID int, PartFamilyID int)
insert into #Part
values (1111,11112),(1112,11114),(1113,11114),(1114,11115),(1115,11115)
declare #PartFamily table (ID int, Name varchar(10))
insert into #PartFamily
values (11111,'A'),(11112,'B'),(11113,'C'),(11114,'D'),(11115,'E')
select *
from #Unit u
left join #Test t
on t.UnitID = u.ID
join #TestDetail td
on td.TestID = t.ID
join #Part p
on p.ID = td.PartID
join #PartFamily pf
on pf.ID = p.PartFamilyID
and pf.Name <> 'B'
However, the query excludes the rows where t.ID is NULL, so only the non-NULL t.ID rows for units 2 and 4 are left.
I have tried a variety of combinations of different types of joins without success.
Ultimately, I want to use the query to update a table:
update r
set r.Value = case when t.ID is not NULL then 'Yes' else 'No' end
from #Results r
left join #Unit u
on u.ID = r.UnitID
left join #Test t
on t.UnitID = u.ID
join #TestDetail td
on td.TestID = t.ID
join #Part p
on p.ID = td.PartID
join #PartFamily pf
on pf.ID = p.PartFamilyID
and pf.Name <> 'B'
select * from #Results
Which actually works when rows are returned.
If the NULL t.ID rows were returned, I expected the case statement to evaluate to Yes when at least one row for a single unit contained a non-NULL t.ID value.
I understand that I can subsequently update #Results where Value is NULL which is fine.
However, I am still trying to understand how to get the rows for all the units to be returned.
I thought that a left join would still leave the unit even when the subsequent (inner) joins return no matches.
If a unit has a match in Test but the test record has no match in TestDetail how can I get the record for the unit (with the NULL values in the columns of the subsequent tables without a match) returned?
Thanks in advance!
you have to do left joins after the left join bec the way you do your update disables the left join of t since t.ID=null won't ever find a TestDetail td
select r.*
, r.ValueNew = case when t.ID is not NULL then 'Yes' else 'No' end
from #Results r
left join #Unit u on u.ID = r.UnitID
left join #Test t on t.UnitID = u.ID
left join #TestDetail td on td.TestID = t.ID
left join #Part p on p.ID = td.PartID
left join #PartFamily pf on pf.ID = p.PartFamilyID and pf.Name <> 'B'
this way, you will have your record r and nothing else

Output Clause: The multi-part identifier could not be bound

I am running in to the dreaded "The multi-part identifier could not be bound" error on a stored procedure I am currently working on. I have a few questions in regards to the query below.
Why am I getting this error?
Why would this error occur on ImportFundingDateTime instead of FloorplanId given that they both come from the same query, but FloorplanId is listed first in the output clause?
Can I adjust this query to not get the error while still keeping the general structure the same?
.
DECLARE #Results Table(
[FloorPlanId] UNIQUEIDENTIFIER,
[ImportFundingDateTime] DATETIME,
[TimeStamp] VARBINARY(8),
[BusinessId] UNIQUEIDENTIFIER
)
UPDATE CacRecord
SET MatchFound = 1
OUTPUT fp.[FloorplanId], cr.[ImportFundingDateTime],
fp.[TimeStamp], buyer.[BusinessId]
INTO #Results( [FloorplanId], [ImportFundingDateTime],
[TimeStamp], [BusinessId])
FROM CacRecord cr WITH (NOLOCK)
INNER JOIN CacBatch cb WITH (NOLOCK)
ON cr.CacBatchId = cb.CacBatchId
INNER JOIN Floorplan fp WITH (NOLOCK)
ON fp.UnitVIN = cr.ImportVin
AND COALESCE(fp.UnitVIN, '') <> ''
INNER JOIN Business buyer WITH (NOLOCK)
ON buyer.BusinessId = fp.BuyerBusinessId
LEFT OUTER JOIN BusinessContact bc WITH (NOLOCK)
ON bc.BusinessId = buyer.BusinessId
LEFT OUTER JOIN Contact c WITH (NOLOCK)
ON c.ContactId = bc.ContactId
WHERE cb.CacJobInstanceId = #cacJobInstanceId
AND fp.FloorplanStatusId = 1 --Approved
AND COALESCE(cr.ImportVin, '') <> ''
AND 1 =
CASE
WHEN cr.ImportFein = buyer.FederalTaxID
AND COALESCE(cr.ImportFein, '') <> '' THEN 1
WHEN cr.ImportSsn = c.Ssn
AND COALESCE(cr.ImportSsn, '') <> '' THEN 1
ELSE 0
END;
Please recheck the syntax of the OUTPUT clause OUTPUT on MSDN
Syntax
<column_name> ::=
{ DELETED | INSERTED | from_table_name } . { * | column_name }
from_table_name
Is a column prefix that specifies a table included in the FROM clause
of a DELETE or UPDATE statement that is used tospecify the rows to
update or delete.
It looks like you have aliased CacRecord in the FROM clause as "cr", but have not correlated that with the UPDATE clause.
Note: Even with it aliases in the FROM clause and NOT aliased in the UPDATE cause, SQL Server appears to recognize CacRecord as the UPDATE table, requiring you to use INSERTED instead of cr as the virtual table name.
UPDATE cr
SET MatchFound = 1
OUTPUT fp.[FloorplanId], INSERTED.[ImportFundingDateTime],
fp.[TimeStamp], buyer.[BusinessId]
INTO #Results( [FloorplanId], [ImportFundingDateTime],
[TimeStamp], [BusinessId])
FROM CacRecord cr WITH (NOLOCK)
INNER JOIN CacBatch cb WITH (NOLOCK)
ON cr.CacBatchId = cb.CacBatchId
INNER JOIN Floorplan fp WITH (NOLOCK)
ON fp.UnitVIN = cr.ImportVin
AND COALESCE(fp.UnitVIN, '') <> ''
INNER JOIN Business buyer WITH (NOLOCK)
ON buyer.BusinessId = fp.BuyerBusinessId
LEFT OUTER JOIN BusinessContact bc WITH (NOLOCK)
ON bc.BusinessId = buyer.BusinessId
LEFT OUTER JOIN Contact c WITH (NOLOCK)
ON c.ContactId = bc.ContactId
WHERE cb.CacJobInstanceId = #cacJobInstanceId
AND fp.FloorplanStatusId = 1 --Approved
AND COALESCE(cr.ImportVin, '') <> ''
AND 1 =
CASE
WHEN cr.ImportFein = buyer.FederalTaxID
AND COALESCE(cr.ImportFein, '') <> '' THEN 1
WHEN cr.ImportSsn = c.Ssn
AND COALESCE(cr.ImportSsn, '') <> '' THEN 1
ELSE 0
END;
For visitors to this question, this code block shows multiple tables being referenced in the OUTPUT clause correctly.
create table TO1 (id int, a int);
create table TO2 (id int, b int);
create table TO3 (id int, c int);
insert into TO1 select 1,1;
insert into TO2 select 1,2;
insert into TO3 select 1,3;
insert into TO3 select 1,4;
declare #catch table (a int, b int, c int)
update c
set c = a.a
output a.a, b.b, INSERTED.c
into #catch(a,b,c)
from TO1 a
inner join TO2 b on a.id=b.id
inner join TO3 c on a.id=c.id