Reputation: 820
I have a string something like
No People,Day,side view,looking at camera,snow,mountain,tranquil scene,tranquility,Night,walking,water,Two Person,looking Down
And I have a table Group_words
Group Category
---------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------
No People,One Person,Two Person,Three Person,Four Person,five person,medium group of people,large group of people,unrecognizable person,real people People
Day,dusk,night,dawn,sunset,sunrise Weather
looking at camera,looking way,looking sideways,looking down,looking up View Angle
I want to check every comma separated word with table Group_words
and find the wrong combination.
For the above string result should be : "No People,Day,side view,looking at camera,snow,mountain,tranquil scene,tranquility,walking,water"
Night
is removed because Day
is available in the string.Two Person
is removed because No People
is available in the string.looking Down
is removed because looking at camera
is available in the string.I know its to complicated but simply I want to remove the not matching words from sting which is available into table Group_words
.
Upvotes: 1
Views: 163
Reputation: 31879
Wow, you should be re-designing your tables. Anyway, here is my attempt using Jeff Moden's DelimitedSplit8k.
I believe you now have this function since I answered one of your previous questions that also uses this function.
First, you want to split your @string
input into separate rows. You should also split the Group_Words
table.
After that you do a LEFT JOIN
to get the matching categories. Then you eliminate the invalid words.
See it in action here: SQL Fiddle
DECLARE @string VARCHAR(8000)
SET @string = 'No People,Day,side view,looking at camera,snow,mountain,tranquil scene,tranquility,Night,walking,water,Two Person,looking Down'
-- Split @string variable
DECLARE @tbl_string AS TABLE(ItemNumber INT, Item VARCHAR(8000))
INSERT INTO @tbl_string
SELECT
ItemNumber, LTRIM(RTRIM(Item))
FROM dbo.DelimitedSplit8K(@string, ',')
-- Normalize Group_Words
DECLARE @tbl_grouping AS TABLE(Category VARCHAR(20), ItemNumber INT, Item VARCHAR(8000))
INSERT INTO @tbl_grouping
SELECT
w.Category, s.ItemNumber, LTRIM(RTRIM(s.Item))
FROM Group_Words w
CROSS APPLY dbo.DelimitedSplit8K(w.[Group], ',')s
;WITH Cte AS(
SELECT
s.ItemNumber,
s.Item,
g.category,
RN = ROW_NUMBER() OVER(PARTITION BY g.Category ORDER BY s.ItemNumber)
FROM @tbl_string s
LEFT JOIN @tbl_grouping g
ON g.Item = s.Item
)
SELECT STUFF((
SELECT ',' + Item
FROM Cte
WHERE
RN = 1
OR Category IS NULL
ORDER BY ItemNumber
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'),
1, 1, '')
OUTPUT:
| |
|--------------------------------------------------------------------------------------------------|
| No People,Day,side view,looking at camera,snow,mountain,tranquil scene,tranquility,walking,water |
If your @string
input has more than 8000
characters, the DelimitedSplit8K
will slow down. You can use other splitters instead. Here is one taken for Sir Aaron Bertrands's article.
CREATE FUNCTION dbo.SplitStrings_XML
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
Upvotes: 2