SQL Server SELECT Sequential Data, Breaking Lines at any Column Diference - sql

I posted a question at MSDN (Brazilian) site. My problem is that I want to make a select at a table that returns a first and last number (from a column) WITHOUT INTERRUPTION and WITHOUT CHANGES on other columns related on the search.
QUESTION UPDATE (2015-04-23)
I've updated my own post on MSDN as on this link. I made a SELECT that would give me almost what i want - but 1 line for the first and 1 line for the final number on each range. It is breaking perfectly, so when the Diag column is O (letter O) means that there is no other number on the range (as O stands for "Only"), so the number would be both initial and final. When the Diag column ins ´F´ is the first number of the range, and due to the ´ORDER BY´ arguments, the last number of that range (as you may guess, with an ´L´ for LAST on the Diag column) is right below it, on the next line. My task now is to create 1 more column on it and then repeated the enNumber field when Diag is O, place the next line ´enNumber´ value when the ´Diag´ column where ´F´ and eliminate all lines with ´L´ on the ´Diag´ column.
SELECT
[EnT].enPrefix,
[EnT].enNumber,
[EnT].enOrder,
[EnT].enDate,
[EnT].enNfe,
[EnT].enClient,
(CASE
WHEN [EnN].enNumber IS NULL THEN
CASE
WHEN [EnP].enNumber IS NULL THEN 'O'
ELSE 'L'
END
ELSE 'F'
END) AS [Diag]
FROM
SerialsDB.dbo.Entries AS [EnT]
LEFT OUTER JOIN SerialsDB.dbo.Entries AS [EnN]
ON ([EnT].enProduct = [EnN].enProduct) AND
([EnN].enNumber = [EnT].enNumber + 1) AND
([EnN].enOrder = [EnT].enOrder) AND
([EnN].enClient = [EnT].enClient) AND
([EnN].enNfe = [EnT].enNfe) AND
([EnN].enDate = [EnT].enDate)
LEFT OUTER JOIN SerialsDB.dbo.Entries AS [EnP]
ON ([EnT].enProduct = [EnP].enProduct) AND
([EnP].enNumber = [EnT].enNumber - 1) AND
([EnP].enOrder = [EnT].enOrder) AND
([EnP].enClient = [EnT].enClient) AND
([EnP].enNfe = [EnT].enNfe) AND
([EnP].enDate = [EnT].enDate)
WHERE
([EnT].enOrder IS NOT NULL) AND
([EnT].enClient IS NOT NULL) AND
(([EnP].enNumber IS NULL) OR
([EnN].enNumber IS NULL))
ORDER BY
[EnT].enOrder ASC,
[EnT].enDate ASC,
[EnT].enNfe ASC,
[EnT].enPrefix ASC,
[EnT].enNumber ASC
Help!

This is not going to be a simple query using a GROUP BY.
For simplicity and to show the basic idea I assume Entries table just got two columns: enNumber and enProduct. You can add all other columns and criteria later.
CREATE TABLE [Entries](
[enNumber] [int] NOT NULL,
[enProduct] [int] NOT NULL,
CONSTRAINT [PK_Entries] PRIMARY KEY CLUSTERED ([enNumber] ASC) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO [Entries] VALUES (1000309,2768)
INSERT INTO [Entries] VALUES (1000310,2768)
INSERT INTO [Entries] VALUES (1000311,2768)
INSERT INTO [Entries] VALUES (1000312,2768)
INSERT INTO [Entries] VALUES (1000313,2768)
INSERT INTO [Entries] VALUES (1000314,2768)
INSERT INTO [Entries] VALUES (1000315,2768)
INSERT INTO [Entries] VALUES (1000316,2768)
INSERT INTO [Entries] VALUES (1000317,2768)
/* interrupt */
INSERT INTO [Entries] VALUES (1001388,3328)
INSERT INTO [Entries] VALUES (1001389,3328)
INSERT INTO [Entries] VALUES (1001390,3328)
INSERT INTO [Entries] VALUES (1001391,3328)
INSERT INTO [Entries] VALUES (1001392,3328)
/* change */
INSERT INTO [Entries] VALUES (1001393,3743)
INSERT INTO [Entries] VALUES (1001394,3743)
INSERT INTO [Entries] VALUES (1001395,3743)
INSERT INTO [Entries] VALUES (1001396,3743)
/* change */
INSERT INTO [Entries] VALUES (1001397,3328)
INSERT INTO [Entries] VALUES (1001398,3328)
INSERT INTO [Entries] VALUES (1001399,3328)
INSERT INTO [Entries] VALUES (1001400,3328)
/* interrupt */
INSERT INTO [Entries] VALUES (1003000,2768)
/* change */
INSERT INTO [Entries] VALUES (1003001,3328)
INSERT INTO [Entries] VALUES (1003002,3328)
INSERT INTO [Entries] VALUES (1003003,3328)
GO
Create two views, one of them giving all the records that act as the initial of a group and another view for the finals.
A record is an initial/final record if the previous/next enNumber does not exist (an interrupt) or has different values (a change).
CREATE VIEW [Initials] AS
SELECT E.enNumber
FROM Entries E
LEFT JOIN Entries E2 on E2.enNumber = E.enNumber - 1
AND E2.enProduct= E.enProduct
WHERE E2.enNumber IS NULL
GO
CREATE VIEW [Finals] AS
SELECT E.enNumber
FROM Entries E
LEFT JOIN Entries E2 on E2.enNumber = E.enNumber + 1
AND E2.enProduct= E.enProduct
WHERE E2.enNumber IS NULL
GO
Each record in Initials has a counterpart in Finals with an enNumber equal or greater than its enNumber.
SELECT i.enNumber AS Initial, E.enProduct
FROM Initials i
LEFT JOIN Entries E ON E.enNumber = i.enNumber
SELECT f.enNumber AS Final, E.enProduct
FROM Finals f
LEFT JOIN Entries E ON E.enNumber = f.enNumber
Initial enProduct
1000309 2768
1001388 3328
1001393 3743
1001397 3328
1003000 2768
1003001 3328
Final enProduct
1000317 2768
1001392 3328
1001396 3743
1001400 3328
1003000 2768
1003003 3328
You can combine these two views in different ways to achieve the desired results:
SELECT i.enNumber AS initial, MIN(f.enNumber) AS final, E.enProduct
FROM Initials i
LEFT JOIN finals f ON f.enNumber >= i.enNumber
LEFT JOIN Entries E ON E.enNumber = i.enNumber
GROUP BY i.enNumber, E.enProduct
ORDER BY i.enNumber
initial final enProduct
1000309 1000317 2768
1001388 1001392 3328
1001393 1001396 3743
1001397 1001400 3328
1003000 1003000 2768
1003001 1003003 3328

I think you need to do this with subquery. In the subquery, you will get the min and max values and include the columns you want to sort by. In the main query, you will select all columns. See the following link for details:
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
Section "Selecting the one maximum row from each group"

I've wrote a query and got the results i was trying to find. I still don't like it very much as i think it will have a big cost on the database to run it, and i'd like to find one simpler. But anyway, the "problem" it self is resolved.
The resulting query is writen as follows:
SELECT
[Pre].[pfPrefix],
[Pro].[prId],
[Pro].[prName],
(CASE
WHEN [EnP].[enNumber] IS NULL THEN [EnT].[enNumber]
ELSE
(SELECT TOP 1
[iET].[enNumber]
FROM
[SerialsDB].[dbo].[Entries] AS [iET]
LEFT OUTER JOIN [SerialsDB].[dbo].[Entries] AS [iEP]
ON (([iEP].[enProduct] IS NULL AND [iET].[enProduct] IS NULL) OR
([iEP].[enProduct] = [iET].[enProduct])) AND
(([iEP].[enOrder] IS NULL AND [iET].[enOrder] IS NULL) OR
([iEP].[enOrder] = [iET].[enOrder])) AND
(([iEP].[enClient] IS NULL AND [iET].[enClient] IS NULL) OR
([iEP].[enClient] = [iET].[enClient])) AND
(([iEP].[enNfe] IS NULL AND [iET].[enNfe] IS NULL) OR
([iEP].[enNfe] = [iET].[enNfe])) AND
(([iEP].[enDate] IS NULL AND [iET].[enDate] IS NULL) OR
([iEP].[enDate] = [iET].[enDate])) AND
(([iEP].[enAuth] IS NULL AND [iET].[enAuth] IS NULL) OR
([iEP].[enAuth] = [iET].[enAuth])) AND
(([iEP].[enStatus] IS NULL AND [iET].[enStatus] IS NULL) OR
([iEP].[enStatus] = [iET].[enStatus])) AND
([iEP].[enNumber] = ([iET].[enNumber] - 1))
WHERE
(([iET].[enProduct] IS NULL AND [EnT].[enProduct] IS NULL) OR
([iET].[enProduct] = [EnT].[enProduct])) AND
(([iET].[enOrder] IS NULL AND [EnT].[enOrder] IS NULL) OR
([iET].[enOrder] = [EnT].[enOrder])) AND
(([iET].[enDate] IS NULL AND [EnT].[enDate] IS NULL) OR
([iET].[enDate] = [EnT].[enDate])) AND
(([iET].[enClient] IS NULL AND [EnT].[enClient] IS NULL) OR
([iET].[enClient] = [EnT].[enClient])) AND
(([iET].[enNfe] IS NULL AND [EnT].[enNfe] IS NULL) OR
([iET].[enNfe] = [EnT].[enNfe])) AND
(([iET].[enAuth] IS NULL AND [EnT].[enAuth] IS NULL) OR
([iET].[enAuth] = [EnT].[enAuth])) AND
(([iET].[enStatus] IS NULL AND [EnT].[enStatus] IS NULL) OR
([iET].[enStatus] = [EnT].[enStatus])) AND
([iET].[enNumber] <= [EnP].[enNumber]) AND
([iEP].[enNumber] IS NULL)
ORDER BY
[iET].[enNumber] DESC)
END) AS [Initial],
[EnT].[enNumber] AS [Final],
[EnT].[enOrder],
[EnT].[enDate],
[EnT].[enNfe],
[EnT].[enClient],
[Cli].[clGroup],
[EnT].[enAuth]
FROM
[SerialsDB].[dbo].Entries AS [EnT]
LEFT OUTER JOIN [SerialsDB].[dbo].[Entries] AS [EnN]
ON ([EnN].[enProduct] = [EnT].[enProduct]) AND
([EnN].[enOrder] = [EnT].[enOrder]) AND
([EnN].[enClient] = [EnT].[enClient]) AND
(([EnN].[enNfe] IS NULL AND [EnT].[enNfe] IS NULL) OR
([EnN].[enNfe] = [EnT].[enNfe])) AND
([EnN].[enDate] = [EnT].[enDate]) AND
([EnN].[enStatus] = [EnT].[enStatus]) AND
([EnN].[enAuth] = [EnT].[enAuth]) AND
([EnN].[enNumber] = ([EnT].[enNumber] + 1))
LEFT OUTER JOIN [SerialsDB].[dbo].[Entries] AS [EnP]
ON ([EnP].[enProduct] = [EnT].[enProduct]) AND
([EnP].[enOrder] = [EnT].[enOrder]) AND
([EnP].[enClient] = [EnT].[enClient]) AND
(([EnP].[enNfe] IS NULL AND [EnT].[enNfe] IS NULL) OR
([EnP].[enNfe] = [EnT].[enNfe])) AND
([EnP].[enDate] = [EnT].[enDate]) AND
([EnP].[enStatus] = [EnT].[enStatus]) AND
([EnP].[enAuth] = [EnT].[enAuth]) AND
([EnP].[enNumber] = ([EnT].[enNumber] - 1))
LEFT OUTER JOIN [SerialsDB].[dbo].[Prefixes] AS [Pre]
ON ([EnT].[enPrefix] = [Pre].[pfId])
LEFT OUTER JOIN [SerialsDB].[dbo].[Products] AS [Pro]
ON ([EnT].[enProduct] = [Pro].[prId])
LEFT OUTER JOIN [SerialsDB].[dbo].[Clients] AS [Cli]
ON ([EnT].[enClient] = [Cli].[clId])
WHERE
([EnT].[enOrder] IS NOT NULL) AND
([EnT].[enClient] IS NOT NULL) AND
([EnN].[enNumber] IS NULL) AND
([EnT].[enStatus] = 4) AND
([EnT].[enAuth] IS NOT NULL)
Thank you Amir for the great inputs, and for Stamen for the suggestion.

Related

insert into select oracle

i need insert rows on a table that comes of other, the colums in the table are empty but in te base table are full, im using a insert into select but i get: 'Error SQL: ORA-00926'
INSERT INTO TABLEROS.V_GRR_EEAF (PER_ID, EDAD, F_NACIMIENTO, CICLO_VITAL, GENERO_HOM, PERT_ETNICA, DISCAP
)A
(SELECT PER_ID, EDAD, F_NACIMIENTO, CICLO_VITAL, GENERO_HOM, PERT_ETNICA, DISCAP
FROM FUENTES.V_GRR_EEAF#CONSULTAFUENTES80 B
WHERE A.ID_BASE = B.ID_BASE
);
If I understand, you want to update empty columns in A where id_base exists in B and the updated values should be same as columns in B.
use this statement, it works:
MERGE INTO TABLEROS.V_GRR_EEAF a
USING FUENTES.V_GRR_EEAF#CONSULTAFUENTES80 b
ON(a.ID_BASE = b.ID_BASE)
WHEN MATCHED THEN
UPDATE SET
a.PER_ID = b.PER_ID,
a.EDAD = b.EDAD,
a.F_NACIMIENTO = b.F_NACIMIENTO,
a.CICLO_VITAL = b.CICLO_VITAL,
a.GENERO_HOM = b.GENERO_HOM,
a.PERT_ETNICA = b.PERT_ETNICA,
a.DISCAP = b.DISCAP;
commit;

SQL sum() not adding up correctly

I have the following Temp table and Insert statement:
declare #ClaimNumbers table (ClaimId Id_t, ClaimNumber RefNumber_t, AmtPaid Money_t, RecordStatus Code_t null, Amount Money_t null, ProcessingStatus code_t null)
insert into #ClaimNumbers
(
ClaimNumber,
ClaimId,
AmtPaid,
RecordStatus,
Amount,
ProcessingStatus
)
select
E.ReferenceNumber,
E.ClaimId,
sum(E.AmtPaid),
CBR.RecordStatus,
sum(CBR.Amount),
C.ProcessingStatus
from EDIXacts E
left join ClaimBillingRecords CBR
on CBR.ClaimId = E.ClaimId
and CBR.BillingEntityMapId in (select BillingEntityMapId from BillingEntityMap where BillingEntityId = 255) --#BillingEntityId)
and CBR.RecordStatus = 'POS'
left join Claims C on C.ClaimId = E.ClaimId
where E.CheckId = 1747 --#CheckId
and XactType = 'RMT'
and XactStatus in ('NRM','SLM')
group by E.ReferenceNumber,
E.ClaimId,
CBR.RecordStatus,
C.ProcessingStatus
Given example data:
ClaimBillingRecords
ClaimId,RecordStatus,Amount
3807,'POS',-100
3807,'POS',120
EDIXacts
XactType,XactStatus,CheckId,AmtPaid
'RMT','NRM',1747,-100
'RMT','SLM',1747,120
I am expecting the Amount to be $20 and the AmtPaid to be $20, however I am getting Amount: $40 and AmtPaid: $40.
Is there something I am doing wrong with the aggregate function?
Without having complete table structures with valid sample data it's hard to tell what's wrong. My guess is your rows are being multiplied through joining. Please check below select query to check the data first then use group by to sum those.
declare #ClaimNumbers table (ClaimId Id_t, ClaimNumber RefNumber_t, AmtPaid Money_t, RecordStatus Code_t null, Amount Money_t null, ProcessingStatus code_t null)
insert into #ClaimNumbers
(
ClaimNumber,
ClaimId,
AmtPaid,
RecordStatus,
Amount,
ProcessingStatus
)
select
E.ReferenceNumber,
E.ClaimId,
sum(E.AmtPaid),
CBR.RecordStatus,
sum(CBR.Amount),
C.ProcessingStatus
from EDIXacts E
left join ClaimBillingRecords CBR
on CBR.ClaimId = E.ClaimId
and CBR.BillingEntityMapId in (select BillingEntityMapId from BillingEntityMap where BillingEntityId = 255) --#BillingEntityId)
and CBR.RecordStatus = 'POS'
left join Claims C on C.ClaimId = E.ClaimId
where E.CheckId = 1747 --#CheckId
and XactType = 'RMT'
and XactStatus in ('NRM','SLM')
Hope you will get the idea why Amount and AmountPaid column is having double the expected amount.

Pull data from two tables and provide all data elements

I have one table that I created with Names, SSN, and dates. I want to look inside another table and still pull all the info from my first table, but also if the name is found in the second table, provide that data. If not, provide a Null Value. I believe this is a left join, but may be mistaken.
This is my code:
if object_id('tempdb..#ssns') is not null drop table #ssns
create table #ssns
(ssnId int, fName varchar(50), ssn varchar(20), ReqDate datetime2(0))
insert into #ssns values (1,'test,test','0001','20180621'),
if object_id('tempdb..#pt') is not null drop table #pt
select a.*, b.patientSID, b.patientName, b.patientSSN, b.DeathDateTime
into #pt
from #ssns a
join spatient.spatient b on b.patientname = a.fname
where b.sta3n = 558 and RIGHT(b.patientSSN,4) = a.ssn
if object_id('tempdb..#ptappt') is not null drop table #ptappt
select a.*, c.locationName, d.stopCode, b.appointmentDateTime, b.appointmentStatus
into #ptappt
from #pt a
left join LSV.D01_VISN06.cci_Appt_Appointment b on b.patientSID = a.patientSID and b.sta3n = 558
join dim.location c on c.locationSID = b.locationSID and c.sta3n = 558
join dim.stopCode d on d.stopCodeSID = c.primaryStopCodeSID and d.sta3n = 558
where isnull(b.AppointmentStatus,'Null') not in ('C', 'CA')
and appointmentDateTime >= a.reqDate
and d.stopCode in ('323', '322', '350')
I found my answer. You filter the where clause on the join:
from #pt a
left join LSV.D01_VISN06.cci_Appt_Appointment b on b.patientSID = a.patientSID and b.sta3n = 558 and
isnull(b.AppointmentStatus,'Null') not in ('C', 'CA')
and appointmentDateTime >= a.reqDate
left join dim.location c on c.locationSID = b.locationSID and c.sta3n = 558
left join dim.stopCode d on d.stopCodeSID = c.primaryStopCodeSID and d.sta3n = 558
and d.stopCode in ('323', '322', '350')

MERGE statement using OUTPUT with WHERE condition

I'm trying to insert data from one system into another so I keep an intermediate mapping table to keep the ids from old and new table.
I'm using a MERGE condition, is there any way to
DECLARE #TenantId INT = 1
MERGE dbo.[Account] AS t
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = #TenantId
) AS s
ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId])
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (#TenantId, s.[Account_No], s.[Account_Name], 1)
OUTPUT #TenantId, inserted.[AccountId], s.[ID_Account] INTO migration.[Account];
This is fine, but if I try to run it a second time, the records are inserted again on my migration.[Account] table keeping repeated data. Is there any way to put a where condition on the output?
When you check to see if values from the source exist in the target, you check to see if the AccountId from migration.Account is equal to the AccountId from dbo.Account. You output the results to the migration table, but the original record still exists so it will be included in subsequent executions of the merge.
To fix your problem you need to either:
delete the original record
Add an isUpdated column in the migration table that you update after insertion and will prevent the source from being loaded.
Update the AccountId with the new AccountId so it will match the condition on subsequent executions.
Have the new record somehow cancel the original in the source record.
Here's a method with a new isUpdated and updates the accountId column:
UPDATE m SET
isUpdated = 1,
AccountId = o.NewAccountId
FROM migration.Account [m]
INNER JOIN (
MERGE dbo.[Account] AS t
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account]
AND m.[TenantId] = #TenantId
WHERE m.isUpdated IS NULL OR m.isUpdated = 0
) AS s
ON (t.[AccountId] = s.[AccountId] AND t.[TenantId] = s.[TenantId])
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (#TenantId, s.[Account_No], s.[Account_Name], 1)
OUTPUT #TenantId, s.AccountId [OriginalAccountId], inserted.[NewAccountId]
) [o] ON o.TenantId = m.TenantId AND o.OriginalAccountId = m.AccountId
What you want to do is do updates on when matched:
MERGE into dbo.[Account] AS destination
USING (SELECT m.[AccountId],
m.[TenantId],
a.[ID_Account],
a.[Account_No],
a.[Account_Name],
FROM [Client1].dbo.[Account] a
LEFT JOIN migration.[Account] m ON m.[ID_Account] = a.[ID_Account] AND m.[TenantId] = #TenantId
) AS holdinarea
ON (destination.[AccountId] = holdinarea.[AccountId] AND destination.[TenantId] = holdinarea.[TenantId])
WHEN MATCHED THEN
UPDATE set [AccountId]=holdinarea.accountid,
[TenantId]=holdinarea.tenantID
WHEN NOT MATCHED THEN
INSERT ([TenantId], [Number], [Name], [Active] )
VALUES (holdingarea.TenantId, holdingarea.[Account_No], holdingarea.[Account_Name], 1);

WHERE IS NULL Not Working in Nested Select

INSERT INTO AutomatedTest_XMLReconciliation(TaskID, TestCaseID, TestInstanceID, XMLHierarchyLevelID, XMLNode, XMLValue_Truth, XMLValue_Test)
(
(SELECT A.TaskID, A.TestCaseID, NULL, A.XMLHierarchyLevelID, A.XMLNode, A.XMLValue_Truth, NULL
FROM AutomatedTest_XMLTruthData A
LEFT JOIN AutomatedTest_Auth B
ON A.TestCaseID = B.TestCaseID
FULL Join AutomatedTest_XMLTestData C
ON B.TestInstanceID = C.TestInstanceID AND A.TruthIdentity = C.TestIdentity AND A.XMLHierarchyLevelID = C.XMLHierarchyLevelID AND A.XMLNode = C.XMLNode AND A.TaskID = C.TaskID
WHERE (B.ReconcileDate IS NULL AND A.TaskID IS NOT NULL)
EXCEPT
(Select A.TaskID, A.TestCaseID, NULL, A.XMLHierarchyLevelID, A.XMLNode, A.XMLValue_Truth, NULL
FROM AutomatedTest_XMLTruthData A
INNER JOIN AutomatedTest_Auth B
ON A.TestCaseID = B.TestCaseID
INNER JOIN AutomatedTest_XMLTestData C
ON B.TestInstanceID = C.TestInstanceID AND A.TruthIdentity = C.TestIdentity AND A.XMLHierarchyLevelID = C.XMLHierarchyLevelID AND A.XMLNode = C.XMLNode AND A.TaskID = C.TaskID)
)
UNION
(SELECT C.TaskID, NULL, C.TestInstanceID, C.XMLHierarchyLevelID, C.XMLNode, NULL, C.XMLValue_Test
FROM AutomatedTest_XMLTruthData A
LEFT JOIN AutomatedTest_Auth B
ON A.TestCaseID = B.TestCaseID
FULL JOIN AutomatedTest_XMLTestData C
ON B.TestInstanceID = C.TestInstanceID AND A.TruthIdentity = C.TestIdentity AND A.XMLHierarchyLevelID = C.XMLHierarchyLevelID AND A.XMLNode = C.XMLNode AND A.TaskID = C.TaskID
WHERE B.ReconcileDate IS NULL AND C.TaskID IS NOT NULL)
EXCEPT
(Select C.TaskID, NULL, C.TestInstanceID, C.XMLHierarchyLevelID, C.XMLNode, NULL, C.XMLValue_Test
FROM AutomatedTest_XMLTruthData A
INNER JOIN AutomatedTest_Auth B
ON A.TestCaseID = B.TestCaseID
INNER JOIN AutomatedTest_XMLTestData C
ON B.TestInstanceID = C.TestInstanceID AND A.TruthIdentity = C.TestIdentity AND A.XMLHierarchyLevelID = C.XMLHierarchyLevelID AND A.XMLNode = C.XMLNode AND A.TaskID = C.TaskID)
))
UPDATE AutomatedTest_Auth
SET ReconcileDate = GETDATE()
WHERE (TestCaseID IN (Select TestCaseID FROM AutomatedTest_DataReconciliation WHERE TestCaseID IS NOT NULL)
OR TestInstanceID IN (Select TestInstanceID FROM AutomatedTest_DataReconciliation WHERE TestInstanceID IS NOT NULL))
AND ReconcileDate IS NULL
So I've got this insert query that is meant to check two tables, one test and one auth, and compare their rows. It matches a TestInstance in the test table with a TestCase in a truth table through the AutomatedTest_Auth table.
Once it is done, it updates the AutomatedTest_Auth table with the GETDATE() stamp to show that the reconciliation process is complete. The insert checks this in the WHEREs to make sure that it does not insert anything that is already inserted by making sure the ReconcileDate IS NULL (it defaults to null on upon a new entry into the AutomatedTest_Auth table).
My problem, however, is that the second "B.Reconcile IS NULL" is not working. Upon running this twice, it will pick up the same rows from AutomatedTest_XMLTestData it picked up the first time and insert them again. (Just a note, there is no PK violation, as the Reconciliation columns could overlap at any time; it has an identity column instead).
Is this an order of operations issue? ... a bug? Any help would be nice.
Also, when I change the B.ReconcileDate IS NULL to IS NOT NULL, the insert swaps, and it will instead insert the same rows from AutomatedTest_XMLTruthData and not AutomatedTest_XMLTestData, so I know the inserts from AutomatedTest_XMLTruthData are correctly recognizing the WHERE clause, and that AutomatedTest_XMLTestData is incorrectly inverting the B.ReconcileData IS NULL to IS NOT NULL.
You are inserting into a table called AutomatedTest_XMLReconciliation
The update where condition looks at a table called AutomatedTest_DataReconciliation which is not referenced elsewhere in your script. Is this correct? I think the Update should be:
UPDATE AUTOMATEDTEST_AUTH
SET RECONCILEDATE = GETDATE()
WHERE ( TESTCASEID IN (SELECT TESTCASEID
FROM AUTOMATEDTEST_XMLRECONCILIATION
WHERE TESTCASEID IS NOT NULL)
OR TESTINSTANCEID IN (SELECT TESTINSTANCEID
FROM AUTOMATEDTEST_XMLRECONCILIATION
WHERE TESTINSTANCEID IS NOT NULL) )
AND RECONCILEDATE IS NULL