'Simple' SQL Search query - sql

Ok, so I'm working on a basic search SPROC.
One of the Parameters is a search text (this will be the test the user enters in, words separated by spaces etc.)
Now all I need is to search these words on a single column in a table, BUT I want it to have ALL the keywords that were entered (at the moment all I can do is if 1 of them is there)
So is there a special SQL command that allows me to do this?

You can try something like this
check the occurances of the words required, and compare to the count of split words.
All issue i forsee is matches to partial words, but this might get you started
/*
ALTER FUNCTION [dbo].[SplitString]
(
#String VARCHAR(8000) ,
#Delimiter VARCHAR(10)
)
RETURNS #RetTable TABLE(
String varchar(1000)
)
AS
BEGIN
DECLARE #i INT ,
#j INT
SELECT #i = 1
WHILE #i <= LEN(#String)
BEGIN
SELECT #j = CHARINDEX(#Delimiter, #String, #i)
IF #j = 0
BEGIN
SELECT #j = LEN(#String) + 1
END
INSERT #RetTable SELECT SUBSTRING(#String, #i, #j - #i)
SELECT #i = #j + LEN(#Delimiter)
END
RETURN
END
*/
DECLARE #SearchString VARCHAR(MAX)
SELECT #SearchString = 'your,of'
DECLARE #SearchStringTable TABLE(
Words VARCHAR(MAX)
)
DECLARE #TABLE TABLE(
Col VARCHAR(MAX)
)
INSERT INTO #TABLE (Col)
SELECT
'On the Insert tab, the galleries include items that are designed to coordinate with the overall look of your document.'
INSERT INTO #TABLE (Col)
SELECT
'You can use these galleries to insert tables, headers, footers, lists, cover pages, and other document building blocks.'
INSERT INTO #TABLE (Col)
SELECT
'When you create pictures, charts, or diagrams, they also coordinate with your current document look.'
INSERT INTO #SearchStringTable (Words) SELECT * FROM dbo.SplitString(#SearchString,',')
SELECT t.Col,
COUNT(1) AS Number
FROM #TABLE t,
#SearchStringTable s
WHERE CHARINDEX(s.Words,t.Col) > 0
GROUP BY t.Col
HAVING COUNT(1) = (SELECT COUNT(1) FROM #SearchStringTable)

You need to split the #SEARCH_TEXT into the words and ideally store it in a temporary table #FILTER_TABLE with one column WORD containing the words. You can google for "sql comma split ...", but answer to this question might be helpful. This is also interesting.
Then you just use JOIN in your query to filter the rows. The simplest query then that would return all the matches would be:
SELECT t.*
f.WORD
FROM MyTable t
JOIN #FILTER_TABLE f
ON t.MyColumn = f.WORD --// = or LIKE operator
But if you provide an example of your data and expected result, people would could be more helpful.

Related

Find all combinations

My teacher asks an algorithm that find all combinations. I have a set of data and the length can be variable. So combinations should be like this:
a
b
c
aa
ab
ac
...
ccbc
ccca
cccb
cccc
They will be stored in the "word" table that contains a single varchar field.
I did it with loop because I don't like recursivity and jt has better performance:
DROP PROCEDURE combi;
CREATE PROCEDURE combi
AS
BEGIN
DELETE FROM word
DECLARE #i BIGINT
DECLARE #j INT
DECLARE #word NVARCHAR(24)
DECLARE #str NVARCHAR(62)
DECLARE #combinations BIGINT
DECLARE #currentlength TINYINT
DECLARE #maxcurrentlength TINYINT
SET #maxcurrentlength=4
SET #str='azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789' -- length=62
SET #currentlength=1
-- loop on the length of the text
WHILE #currentlength<=#maxcurrentlength BEGIN
SET #combinations=POWER(62,#currentlength)
SET #i=0
-- get all combinations
WHILE i<#combinations BEGIN
SET #word=''
SET #j=0
-- generate word
WHILE #j<#currentlength BEGIN
SET #word=#word+SUBSTRING(#str, (FLOOR(#i / POWER(62,#currentlength-#j-1) ) % 62) +1, 1)
SET #j=#j+1
END
INSERT INTO word VALUES (#word)
SET #i=#i+1
END
SET #currentlength=#currentlength+1
END
END;
EXEC combi;
The problem is when I use a length of 8, my server crashes: it seems that POWER(62,#currentlength-#j-1) is the problem.
I'm slightly confused about how you ask the question. You ask to "find all combinations" which could very easily be done with CROSS JOIN. If you need to get a length of 4 then you join the table with available values to itself 4 times and you are pretty much done. If you need to get the strings in 1 field you could concatenate them in the select. Like this:
declare #values table (
value nvarchar(100))
insert #values values ('a'),('b'),('c')
select v1.value+v2.value+v3.value+v4.value
from #values v1 cross join
#values v2 cross join
#values v3 cross join
#values v4
order by v1.value+v2.value+v3.value+v4.value
Here is a generic solution using a recursive CTE:
CREATE TABLE t (i nchar(1))
INSERT INTO t VALUES ('a'),('b'),('c')
;WITH cte AS (
SELECT cast(i AS nvarchar(4000)) AS combo, 1 AS ct
FROM t
UNION ALL
SELECT cte.combo + t.i, ct + 1
FROM cte
CROSS JOIN t
WHERE ct <= 4 -- your maximum length
)
SELECT combo
FROM cte
ORDER BY ct, combo
SQL Fiddle.
You must be aware that the number of results grows exponentially with the maximum length, so performance deteriorates rapidly with growing maximum length.
You are likely overflowing the int type you are passing to POWER() as the documentation for power suggests POWER() returns the same type you feed it.
Try using:
SET #word=#word+SUBSTRING(#str, (FLOOR(#i / POWER(CAST(62 AS BIGINT),#currentlength-#j-1) ) % 62) +1, 1)
If you need to parameterise it so that you can set the required length then this algorithm would do it and it's more relational database orientated.
declare #characters table (character nchar(1))
declare #words table (word nvarchar(100))
insert #characters values ('a'),('b'),('c')
INSERT #words (word ) VALUEs ('')
DECLARE #Required_length int
DECLARE #length int
SET #Required_length = 4
SET #length = 0
WHILE #length <= #Required_length
BEGIN
SET #length = #length+1
INSERT #words (word )
SELECT w.word + c.character
FROM #words w JOIN #characters c ON LEN(w.word) = #length-1
END
SELECT word from #words where len(word) = #Required_length
Start with a zero length word
Add all the possible characters to the zero length word to get all
the one character words
Add all the possible characters to the end of all the one character
words to get all the two character words
Add all the possible characters to the end of all the two character words
to get all the three character words
etc....
You can make it run more efficiently by including the length as a column in the word table so that you don't need to calculate the lengths when you're filtering by them but as this has been set by your teacher I'm not going to do all your work for you
First insert of all characters
SET NOCOUNT ON;
create table ##chars (col char(1))
declare #i int
set #i=65
while #i<=90 /* A-Z */
begin
insert into ##chars values( CHAR(#i))
set #i=#i+1
end
set #i=97
while #i<=122 /* a-z */
begin
insert into ##chars values( CHAR(#i))
set #i=#i+1
end
set #i=48
while #i<=57 /* 0-9 */
begin
insert into ##chars values( CHAR(#i))
set #i=#i+1
end
Now, set number for combinations
create table ##result(word varchar(10))
declare #wide int
set #wide=4 /* set how many combinations are calculated */
insert into ##result select * from ##chars
while #wide>1
begin
begin tran w
insert into ##result select a.word+b.col from ##result a, ##chars b
commit tran w
set #wide=#wide-1
end
select * from ##result
/*
drop table ##chars
drop table ##result
*/

Dynamically Create tables and Insert into it from another table with CSV values

Have a Table with the CSV Values in the columns as below
ID Name text
1 SID,DOB 123,12/01/1990
2 City,State,Zip NewYork,NewYork,01234
3 SID,DOB 456,12/21/1990
What is need to get is 2 tables in this scenario as out put with the corresponding values
ID SID DOB
1 123 12/01/1990
3 456 12/21/1990
ID City State Zip
2 NewYork NewYork 01234
Is there any way of achieving it using a Cursor or any other method in SQL server?
There are several ways that this can be done. One way that I would suggest would be to split the data from the comma separated list into multiple rows.
Since you are using SQL Server, you could implement a recursive CTE to split the data, then apply a PIVOT function to create the columns that you want.
;with cte (id, NameItem, Name, textItem, text) as
(
select id,
cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) NameItem,
stuff(Name, 1, charindex(',',Name+','), '') Name,
cast(left(text, charindex(',',text+',')-1) as varchar(50)) textItem,
stuff(text, 1, charindex(',',text+','), '') text
from yt
union all
select id,
cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) NameItem,
stuff(Name, 1, charindex(',',Name+','), '') Name,
cast(left(text, charindex(',',text+',')-1) as varchar(50)) textItem,
stuff(text, 1, charindex(',',text+','), '') text
from cte
where Name > ''
and text > ''
)
select id, SID, DOB
into table1
from
(
select id, nameitem, textitem
from cte
where nameitem in ('SID', 'DOB')
) d
pivot
(
max(textitem)
for nameitem in (SID, DOB)
) piv;
See SQL Fiddle with Demo. The recursive version will work great but if you have a large dataset, you could have some performance issues so you could also use a user defined function to split the data:
create FUNCTION [dbo].[Split](#String1 varchar(MAX), #String2 varchar(MAX), #Delimiter char(1))
returns #temptable TABLE (colName varchar(MAX), colValue varchar(max))
as
begin
declare #idx1 int
declare #slice1 varchar(8000)
declare #idx2 int
declare #slice2 varchar(8000)
select #idx1 = 1
if len(#String1)<1 or #String1 is null return
while #idx1 != 0
begin
set #idx1 = charindex(#Delimiter,#String1)
set #idx2 = charindex(#Delimiter,#String2)
if #idx1 !=0
begin
set #slice1 = left(#String1,#idx1 - 1)
set #slice2 = left(#String2,#idx2 - 1)
end
else
begin
set #slice1 = #String1
set #slice2 = #String2
end
if(len(#slice1)>0)
insert into #temptable(colName, colValue) values(#slice1, #slice2)
set #String1 = right(#String1,len(#String1) - #idx1)
set #String2 = right(#String2,len(#String2) - #idx2)
if len(#String1) = 0 break
end
return
end;
Then you can use a CROSS APPLY to get the result for each row:
select id, SID, DOB
into table1
from
(
select t.id,
c.colname,
c.colvalue
from yt t
cross apply dbo.split(t.name, t.text, ',') c
where c.colname in ('SID', 'DOB')
) src
pivot
(
max(colvalue)
for colname in (SID, DOB)
) piv;
See SQL Fiddle with Demo
You'd need to approach this as a multi-step ETL project. I'd probably start with exporting the two types of rows into a couple staging tables. So, for example:
select * from yourtable /* rows that start with a number */
where substring(text,1,1) in
('0','1','2','3','4','5','6','7','8','9')
select * from yourtable /* rows that don't start with a number */
where substring(text,1,1)
not in ('0','1','2','3','4','5','6','7','8','9')
/* or simply this to follow your example explicitly */
select * from yourtable where name like 'sid%'
select * from yourtable where name like 'city%'
Once you get the two types separated then you can split them out with one of the already written split functions found readily out on the interweb.
Aaron Bertrand (who is on here often) has written up a great post on the variety of ways to split comma delimted strings using SQL. Each of the methods are compared and contrasted here.
http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings
If your row count is minimal (under 50k let's say) and it's going to be a one time operation than pick the easiest way and don't worry too much about all the performance numbers.
If you have a ton of rows or this is an ETL process that will run all the time then you'll really want to pay attention to that stuff.
A simple solution using cursors to build temporary tables. This has the limitation of making all columns VARCHAR and would be slow for large amounts of data.
--** Set up example data
DECLARE #Source TABLE (ID INT, Name VARCHAR(50), [text] VARCHAR(200));
INSERT INTO #Source
(ID, Name, [text])
VALUES (1, 'SID,DOB', '123,12/01/1990')
, (2, 'City,State,Zip', 'NewYork,NewYork,01234')
, (3, 'SID,DOB', '456,12/21/1990');
--** Declare variables
DECLARE #Name VARCHAR(200) = '';
DECLARE #Text VARCHAR(1000) = '';
DECLARE #SQL VARCHAR(MAX);
--** Set up cursor for the tables
DECLARE cursor_table CURSOR FAST_FORWARD READ_ONLY FOR
SELECT s.Name
FROM #Source AS s
GROUP BY Name;
OPEN cursor_table
FETCH NEXT FROM cursor_table INTO #Name;
WHILE ##FETCH_STATUS = 0
BEGIN
--** Dynamically create a temp table with the specified columns
SET #SQL = 'CREATE TABLE ##Table (' + REPLACE(#Name, ',', ' VARCHAR(50),') + ' VARCHAR(50));';
EXEC(#SQL);
--** Set up cursor to insert the rows
DECLARE row_cursor CURSOR FAST_FORWARD READ_ONLY FOR
SELECT s.Text
FROM #Source AS s
WHERE Name = #Name;
OPEN row_cursor;
FETCH NEXT FROM row_cursor INTO #Text;
WHILE ##FETCH_STATUS = 0
BEGIN
--** Dynamically insert the row
SELECT #SQL = 'INSERT INTO ##Table VALUES (''' + REPLACE(#Text, ',', ''',''') + ''');';
EXEC(#SQL);
FETCH NEXT FROM row_cursor INTO #Text;
END
--** Display the table
SELECT *
FROM ##Table;
--** Housekeeping
CLOSE row_cursor;
DEALLOCATE row_cursor;
DROP TABLE ##Table;
FETCH NEXT FROM cursor_table INTO #Name;
END
CLOSE cursor_table;
DEALLOCATE cursor_table;

Compare two list items

I am trying to compare a database field which stores list items (comma separated) with unfortunately a variable which is also a list item.
Example:
In this case, a user can belong to multiple groups, and content access is also allocated to multiple groups.
contentid | group
(1) (c,d)
(2) (a,c)
(3) (b)
So, I need to select all content where user is in group (a,c). In this case, contentid 1,2 should be returned.
Here's a safe but slow solution for SQL 2008
BEGIN
-- setup
DECLARE #tbl TABLE (
[contentid] INT
,[group] VARCHAR(MAX)
)
INSERT INTO #tbl VALUES
(1, 'c,d')
,(2, 'a,c')
,(3, 'd')
-- send your request as simple xml
DECLARE #param XML
SET #param = '<g>a</g><g>c</g>'
-- query
SELECT DISTINCT contentid
FROM #tbl t
INNER JOIN #param.nodes('/g') AS t2(g)
ON ',' + t.[group] + ',' LIKE '%,' + t2.g.value('.', 'varchar(max)') + ',%'
END
You just pass your query in as an XML snippet instead of a comma separated list.
If your group names are single characters or you can be sure the names are not character-subsets of each other (ie: GroupA, GroupAB), then the query can be optimized to.
ON t.[group] LIKE '%' + t2.g.value('.', 'varchar(max)') + '%'
If you're using a RDBMS without XML parsing capability you'll have to use string split your query into a temp table and work it that way.
You really should not be using comma separated values inside your columns. It would be much better if the [group] column only contained one value and you had repeated entries with a UNIQUE constraint on the composite (contentid, group).
You might find this question and answer useful : How do I split a string so I can access item x?
Or you could always use something like this :
create function SplitString(
#string varchar(max),
#delimiter char(1)
)
returns #items table (item varchar(max))
as
begin
declare #index int set #index = 0
if (#delimiter is null) set #delimiter = ','
declare #prevdelimiter int set #prevdelimiter = 0
while (#index < len(#string)) begin
if (substring(#string, #index, 1) = #delimiter) begin
insert into #items
select substring(#string, #prevdelimiter, #index-#prevdelimiter)
set #prevdelimiter = #index + 1
end
set #index = #index + 1
end
--last item (or only if there were no delimiters)
insert into #items
select substring(#string, #prevdelimiter, #index - #prevdelimiter + 1)
return
end
go
declare #content table(contentid int, [group] varchar(max))
insert into #content
select 1, 'c,d'
union
select 2, 'a,c'
union
select 3, 'b'
declare #groups varchar(max) set #groups = 'a,c'
declare #grouptable table(item varchar(max))
insert into #grouptable
select * from dbo.SplitString(#groups, ',')
select * From #content
where (select count(*) from #grouptable g1 join dbo.SplitString([group], ',') g2 on g1.item = g2.item) > 0

SQL server - Split and sum of a single cell

I have a table cell of type nvarchar(max) that typically looks like this:
A03 B32 Y660 P02
e.g. a letter followed by a number, separated by spaces. What I want to do is get a sum of all those numbers in a SQL procedure. Something rather simple in other languages, but I am fairly new to SQL and besides it seems to me like a rather clumsy language to play around with strings.
Aaanyway, I imagine it would go like this:
1) Create a temporary table and fill it using a split function
2) Strip the first character of every cell
3) Convert the data to int
4) Update target table.column set to sum of said temporary table.
So I got as far as this:
CREATE PROCEDURE [dbo].[SumCell] #delimited nvarchar(max), #row int
AS
BEGIN
declare #t table(data nvarchar(max))
declare #xml xml
set #xml = N'<root><r>' + replace(#delimited,' ','</r><r>') + '</r></root>'
insert into #t(data)
select
r.value('.','varchar(5)') as item
from #xml.nodes('//root/r') as records(r)
UPDATE TargetTable
SET TargetCell = SUM(#t.data) WHERE id = #row
END
Obviously, the first char stripping and conversion to int part is missing and on top of that, I get a "must declare the scalar variable #t" error...
Question is not very clear so assuming your text is in a single cell like A3 B32 Y660 P20 following snippet can be used to get the sum.
DECLARE #Cell NVARCHAR(400), #Sum INT, #CharIndex INT
SELECT #Cell = 'A3 B32 Y660 P20',#Sum=0
WHILE (LEN(LTRIM(#Cell))>0)
BEGIN
SELECT #CharIndex = CHARINDEX(' ',#Cell,0)
SELECT #Sum = #Sum +
SUBSTRING(#Cell,2,CASE WHEN #CharIndex>2 THEN #CharIndex-2 ELSE LEN(#Cell)-1 END )
SELECT #Cell = SUBSTRING(#Cell,#CharIndex+1,LEN(#Cell))
IF NOT (#CharIndex >0) BREAK;
END
--#Sum has the total of cell numbers
SELECT #Sum
I'm making the assumption that you really want to be able to find the sum of values in your delimited list for a full selection of a table. Therefore, I believe the most complicated part of your question is to split the values. The method I tend to use requires a numbers table, So I'll start with that:
--If you really want to use a temporary numbers table don't use this method!
create table #numbers(
Number int identity(1,1) primary key
)
declare #counter int
set #counter = 1
while #counter<=10000
begin
insert into #numbers default values
set #counter = #counter + 1
end
I'll also create some test data
create table #data(
id int identity(1,1),
cell nvarchar(max)
)
insert into #data(cell) values('A03 B32 Y660 P02')
insert into #data(cell) values('Y72 A12 P220 B42')
Then, I'd put the split functionality into a CTE to keep things clean:
;with split as (
select d.id,
[valOrder] = row_number() over(partition by d.cell order by n.Number),
[fullVal] = substring(d.cell, n.Number, charindex(' ',d.cell+' ',n.Number) - n.Number),
[char] = substring(d.cell, n.Number, 1),
[numStr] = substring(d.cell, n.Number+1, charindex(' ',d.cell+' ',n.Number) - n.Number)
from #data d
join #numbers n on substring(' '+d.cell, n.Number, 1) = ' '
where n.Number <= len(d.cell)+1
)
select id, sum(cast(numStr as int))
from split
group by id

How to compare if two strings contain the same words in T-SQL for SQL Server 2008?

When I compare two strings in SQL Server, there are couple of simple ways with = or LIKE.
I want to redefine equality as:
If two strings contain the same words - no matter in what order - they are equal, otherwise they are not.
For example:
'my word' and 'word my' are equal
'my word' and 'aaamy word' are not
What's the best simple solution for this problem?
I don't think there is a simple solution for what you are trying to do in SQL Server. My first thought would be to create a CLR UDF that:
Accepts two strings
Breaks them into two arrays using the split function on " "
Compare the contents of the two arrays, returning true if they contain the same elements.
If this is a route you'd like to go, take a look at this article to get started on creating CLR UDFs.
Try this... The StringSorter function breaks strings on a space and then sorts all the words and puts the string back together in sorted word order.
CREATE FUNCTION dbo.StringSorter(#sep char(1), #s varchar(8000))
RETURNS varchar(8000)
AS
BEGIN
DECLARE #ResultVar varchar(8000);
WITH sorter_cte AS (
SELECT CHARINDEX(#sep, #s) as pos, 0 as lastPos
UNION ALL
SELECT CHARINDEX(#sep, #s, pos + 1), pos
FROM sorter_cte
WHERE pos > 0
)
, step2_cte AS (
SELECT SUBSTRING(#s, lastPos + 1,
case when pos = 0 then 80000
else pos - lastPos -1 end) as chunk
FROM sorter_cte
)
SELECT #ResultVar = (select ' ' + chunk
from step2_cte
order by chunk
FOR XML PATH(''));
RETURN #ResultVar;
END
GO
Here is a test case just trying out the function:
SELECT dbo.StringSorter(' ', 'the quick brown dog jumped over the lazy fox');
which produced these results:
brown dog fox jumped lazy over quick the the
Then to run it from a select statement using your strings
SELECT case when dbo.StringSorter(' ', 'my word') =
dbo.StringSorter(' ', 'word my')
then 'Equal' else 'Not Equal' end as ResultCheck
SELECT case when dbo.StringSorter(' ', 'my word') =
dbo.StringSorter(' ', 'aaamy word')
then 'Equal' else 'Not Equal' end as ResultCheck
The first one shows that they are equal, and the second does not.
This should do exactly what you are looking for with a simple function utilizing a recursive CTE to sort your string.
Enjoy!
There is no simple way to do this. You are advised to write a function or stored procedure that does he processing involved with this requirement.
Your function can use other functions that split the stings into parts, sort by words etc.
Here's how you can split the strings:
T-SQL: Opposite to string concatenation - how to split string into multiple records
Scenario is as follows. You would want to use a TVF to split the first and the second strings on space and then full join the resulting two tables on values and if you have nulls on left or right you've got inequality otherwise they are equal.
A VERY simple way to do this...
JC65100
ALTER FUNCTION [dbo].[ITS_GetDifCharCount]
(
#str1 VARCHAR(MAX)
,#str2 VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
DECLARE #result INT
SELECT #result = COUNT(*)
FROM dbo.ITS_CompareStrs(#str1,#str2 )
RETURN #result
END
ALTER FUNCTION [dbo].[ITS_CompareStrs]
(
#str1 VARCHAR(MAX)
,#str2 VARCHAR(MAX)
)
RETURNS
#Result TABLE (ind INT, c1 char(1), c2 char(1))
AS
BEGIN
DECLARE #i AS INT
,#c1 CHAR(1)
,#c2 CHAR(1)
SET #i = 1
WHILE LEN (#str1) > #i-1 OR LEN (#str2) > #i-1
BEGIN
IF LEN (#str1) > #i-1
SET #c1 = substring(#str1, #i, 1)
IF LEN (#str2) > #i-1
SET #c2 = substring(#str2, #i, 1)
INSERT INTO #Result([ind],c1,c2)
SELECT #i,#c1,#c2
SELECT #i=#i+1
,#c1=NULL
,#c2=NULL
END
DELETE FROM #Result
WHERE c1=c2
RETURN
END
You can add a precomputed column in the base table that is evaluated in INSERT/UPDATE trigger (or UDF default) that splits, sorts and then concatenates words from the original column.
Then use = to compare these precomputed columns.
There is library called http://www.sqlsharp.com/ that contains a whole range of useful string/math functions.
It has a function called String_CompareSplitValues which does precisely what you want.
I am not sure if it is in the community version or the paid for version.
declare #s1 varchar(50) = 'my word'
declare #s2 varchar(50) = 'word my'
declare #t1 table (word varchar(50))
while len(#s1)>0
begin
if (CHARINDEX(' ', #s1)>0)
begin
insert into #t1 values(ltrim(rtrim(LEFT(#s1, charindex(' ', #s1)))))
set #s1 = LTRIM(rtrim(right(#s1, len(#s1)-charindex(' ', #s1))))
end
else
begin
insert into #t1 values (#s1)
set #s1=''
end
end
declare #t2 table (word varchar(50))
while len(#s2)>0
begin
if (CHARINDEX(' ', #s2)>0)
begin
insert into #t2 values(ltrim(rtrim(LEFT(#s2, charindex(' ', #s2)))))
set #s2 = LTRIM(rtrim(right(#s2, len(#s2)-charindex(' ', #s2))))
end
else
begin
insert into #t2 values (#s2)
set #s2=''
end
end
select case when exists(SELECT * FROM #t1 EXCEPT SELECT * FROM #t2) then 'are not' else 'are equal' end