April 17, 2014 at 4:13 am
i have a message table and a token table i want to search the message based on tokens
DECLARE @message AS TABLE ([Description] VARCHAR(400))
INSERT INTO @message([Description])
VALUES('duplicate')
INSERT INTO @message([Description])
VALUES('Record already deactivated by another user')
INSERT INTO @message([Description])
VALUES('Record already activated by another user')
INSERT INTO @message([Description])
VALUES('Record already terminated by another user')
INSERT INTO @message([Description])
VALUES('Record already modified by another user')
INSERT INTO @message([Description])
VALUES('Record deactivated already by another user')
SELECT * FROM @message
DECLARE @Keyword AS TABLE (id int,Token VARCHAR(20))
INSERT INTO @Keyword
VALUES(1,'already'),(1,'Deactivated'),(2,'modified'),(3,'activated')
/*
DECLARE @Keyword AS TABLE (id int,Token VARCHAR(20))
INSERT INTO @Keyword
VALUES(1,'already'),(1,'Deactivated'),(2,'already'),(3,'activated'),(3,'already')
*/
i want to search the message based on the keyword table
DECLARE @id INT =2
SELECT * FROM @message m
WHERE
EXISTS (SELECT 1 FROM @Keyword k
WHERE k.id =@id AND
m.[Description] LIKE '%'+ k.Token+'%')
i get the expected result, but when I gave the @id value as 1 i am expecting only the matching records
see below
DECLARE @id INT =1
SELECT * FROM @message m
WHERE
EXISTS (SELECT 1 FROM @Keyword k
WHERE k.id =@id AND
m.[Description] LIKE '%'+ k.Token+'%')
/* Expected output
'Record already deactivated by another user'
'Record deactivated already by another user'
*/
I know why it return more than two rows, may be my logic is wrong here, any other logic, or is it possible any new way ?
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 5:09 am
Try this, using Full-text search:
CREATE TABLE tblmessage (ID INT IDENTITY(1,1) NOT NULL,[Description] VARCHAR(400))
INSERT INTO tblmessage([Description])
VALUES('duplicate')
INSERT INTO tblmessage([Description])
VALUES('Record already deactivated by another user')
INSERT INTO tblmessage([Description])
VALUES('Record already activated by another user')
INSERT INTO tblmessage([Description])
VALUES('Record already terminated by another user')
INSERT INTO tblmessage([Description])
VALUES('Record already modified by another user')
INSERT INTO tblmessage([Description])
VALUES('Record deactivated already by another user')
CREATE UNIQUE INDEX PK_tblmessage_ID ON tblmessage(ID)
CREATE FULLTEXT CATALOG fttest AS DEFAULT;
CREATE FULLTEXT INDEX ON tblmessage([Description]) KEY INDEX PK_tblmessage_ID
DECLARE @Keyword AS TABLE (id int,Token VARCHAR(20))
INSERT INTO @Keyword
VALUES(1,'already'),(1,'Deactivated'),(2,'modified'),(3,'activated')
DECLARE @id INT = 1
DECLARE @message varchar(255)
SELECT @message = (STUFF((SELECT ' AND ' + Token FROM @keyword WHERE ID = @id FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1,4,''))
SELECT * FROM tblmessage m
WHERE contains (m.[Description], @message)
DROP TABLE tblmessage
April 17, 2014 at 6:33 am
Thanks for the response, well that answer was promoted by my seniors, but the trouble is we hold lots of columns in a same table, and tons of tables like this, so create full text index and maintain for all that tables and columns is a tedious and complex job, so he takes me to get a more honest answer to resolve this without using a full text index or REGEX or CLR, so on the whole I need to find a solution in TSQL, is it possible to do this kind of stuff in TSQL?
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 6:54 am
Simplest way to fix this, remove the token 'already' as this appears to exist in all the messages. It doesn't make any sense to me to search for 'already' and 'deactivated' together when what you are looking for is simply 'deactivated'. You aren't looking for 'already' and 'activated' or 'already' and 'modified'.
April 17, 2014 at 7:05 am
Thanks for your info, those are some messages to show the user in the front end, out application is data driven that's why we have such messages in our Tables, more over we just do this for remove unwanted data in all of our Customers,
That's only part of the data, I believe I have already told that we have dozens of tables like this
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 7:06 am
Bear in mind that I don't think this is a good idea, but this should do what you want: -
DECLARE @id INT =1;
SELECT *
FROM @message m
WHERE EXISTS (SELECT 1
FROM (SELECT STUFF((SELECT '%' + Token
FROM @Keyword k
WHERE k.id =@id
FOR XML PATH(''), TYPE
).value('.','NVARCHAR(MAX)'),1,1,''
)
)a(tokens)
WHERE m.[Description] LIKE '%'+ a.tokens+'%');
Jeez, no it won't. Ordering of the tokens would cause issues. The post below by "gbritton1" looks far better.
April 17, 2014 at 7:08 am
Your problem is that the token 'already' is matched by all rows in @message except the first one. So, all rows are returned except the first.
I think that you want to only return rows where all of the tokens match. That's a harder problem. Here's one approach that does what you want:
DECLARE @id INT =1
SELECT m.description
FROM @message m
Where 0 < all (
select patindex('%'+ k.token +'%', m.Description)
from @keyword k
where k.id = @id)
April 17, 2014 at 7:28 am
1. You have anerror in your keyword table, both 'already' and 'Deactivated' have id=1
2. Like will not work as 'activated' keyword will find 'activated' and 'Deactivated'
Solution using splitter
SELECT m.[Description]
FROM @message m
CROSS APPLY dbo.DelimitedSplit8K(m.[Description],' ') s
JOIN @Keyword k ON k.Token = s.Item AND k.id IN (1,2)
GROUP BY m.[Description] HAVING COUNT(DISTINCT k.id) = 2
Far away is close at hand in the images of elsewhere.
Anon.
April 17, 2014 at 7:33 am
Thanks , but it only return one record i need both records, i think we are close to the solution, so it is possible
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 7:42 am
i am also found one but it is not good even though i share it
DECLARE @id INT =1;
WITH CteTokens AS(
SELECT ROW_NUMBER() OVER (ORDER BY id) WordCount, Token
FROM @Keyword WHERE id = @id
),
REcursive_Cte AS(
SELECT 1 AS WordCount, m.[Description]
FROM @message m
WHERE EXISTS (SELECT 1
FROM CteTokens c
WHERE m.[Description] LIKE '%'+ c.token+'%' AND c.wordcount =1)
UNION ALL
SELECT m.WordCount +1 AS Worcount, m.[Description]
FROM REcursive_Cte m
WHERE EXISTS (SELECT 1
FROM CteTokens c
WHERE m.[Description] LIKE '%'+ c.token+'%' AND c.WordCount =m.WordCount+1)
)
SELECT * FROM REcursive_Cte WHERE Wordcount = (SELECT COUNT(*) FROM @Keyword WHERE id = @id)
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 8:02 am
thank you people for you time and effort, you people made my day
Every rule in a world of bits and bytes, can be bend or eventually be broken
MyBlog About Common dialog control
A Visualizer for viewing SqlCommand object script [/url]
April 17, 2014 at 10:21 pm
I like the solution above from gbritton1, but nother way of doing which is probably less efficent but perhaps also easier to understand would be
select m.description from @message m
where not exists (select 1 from @keyword k where k.id = @id and m.Description not like '%'+k.token+'%')
Tom
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply