We have a #ValidCode table with list of valid codes like: 'A', 'B', 'C', etc. Another table called #SourceData with input data -- that comes as a combination of valid and invalid tokens (sometimes duplicates).
Ex:
- 'A;B;C' (valid)
- 'A;A;A;A;A;B' (Valid)
- 'ad;df;A;B' (invalid)
Trying to find an optimal query approach to process these strings to find valid rows in #SourceData. See example below:
DROP TABLE IF EXISTS #ValidCode
GO
CREATE TABLE #ValidCode
(
ID INT IDENTITY(1,1)
, Code CHAR(1)
)
INSERT INTO #ValidCode (Code) VALUES ('A'), ('B'), ('C')
GO
DROP TABLE IF EXISTS #SourceData
GO
CREATE TABLE #SourceData
(
ID INT IDENTITY(1,1)
, Codes VARCHAR(500)
, Is_Valid BIT
, Is_Split BIT
)
INSERT INTO #SourceData (Codes)
VALUES ('A;B;C')
, ('B;A')
, ('B;B;B;C;C;A;A;B')
, ('B;Z;1')
, ('B;ss;asd')
SELECT * FROM #ValidCode
SELECT * FROM #SourceData
Query would process the data in #SourceData table and update the Is_Valid flag, so they could be consumed in the subsequent process.
Rules:
- Each and every token must be valid for the entire column row to be valid (rows 1 to 3)
- Even if one token is invalid, then entire row value is invalid (rows 4 & 5)
So, this is the preferred output:
ID | Codes | Is_Valid |
---|---|---|
1 | A;B;C | 1 |
2 | B;A | 1 |
3 | B;B;B;C;C;A;A;B | 1 |
4 | B;Z;1 | 0 |
5 | B;ss;asd | 0 |
Current approach: Loop through each row in #SourceData and split them on delimiter ';', then compare them to the #ValidCode table. If all tokens are individually valid, then mark the row in #SourceData as valid (Is_Valid flag). Else mark as invalid. The WHILE
loop approach works, but is slow.
The #SourceData could have up to 3 million rows. With each row having multiple duplicate valid ('A;A;A;A') and invalid values combination ('A;as;sdf;B')
Is there a better approach?
Thanks!