SQL Server - Ordering Combined Number Strings Prior To Column Insert - sql

I have 2 string columns (thousands of rows) with ordered numbers in each string (there can be zero to ten numbers in each string). Example:
+------------------+------------+
| ColString1 | ColString2 |
+------------------+------------+
| 1;3;5;12; | 4;6' |
+------------------+------------+
| 1;5;10 | 2;26; |
+------------------+------------+
| 4;7; | 3; |
+------------------+------------+
The end result is to combine these 2 columns, sort the numbers in
ascending order and then put each number into individual columns (smallest, 2nd smallest etc).
e.g. Colstring1 is 1;3;5;12; and ColString2 is 4;6; needs to return 1;3;4;5;6;12; which I then use xml to allocated into columns.
Everthing works fine using xml apart from the step to order the numbers (i.e I'm getting 1;3;5;12;4;6; when I combine the strings i.e. not in ascending order).
I've tried put them into a JSON array first to order, thinking I could do a top[1] etc but that did not work.
Any help on how to combine the 2 columns and order them before inserting into columns:
Steps so far:
Example data:
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, ColString1 VARCHAR(50), ColString2 VARCHAR(50));
INSERT INTO #tbl (ColString1, ColString2)
VALUES
('1;3;5;12;', '4;6;'),
('1;5;10;', '2;26;'),
('14;', '3;8;');
XML Approach (Combines strings and puts into columns but not in the correct order):
;WITH Split_Numbers (xmlname)
AS
(
SELECT
CONVERT(XML,'<Names><name>'
+ REPLACE ( LEFT(ColString1+ColString2,LEN(ColString1+ColString2) - 1),';', '</name><name>') + '</name></Names>') AS xmlname
FROM #tbl
)
SELECT
xmlname.value('/Names[1]/name[1]','int') AS Number1,
xmlname.value('/Names[1]/name[2]','int') AS Number2,
xmlname.value('/Names[1]/name[3]','int') AS Number3,
xmlname.value('/Names[1]/name[4]','int') AS Number4,
xmlname.value('/Names[1]/name[5]','int') AS Number5
--etc for additional columns
FROM Split_Numbers
Current Output: numbers not in correct order,
+---------+---------+---------+---------+---------+
| Number1 | Number2 | Number3 | Number4 | Number5 |
+---------+---------+---------+---------+---------+
| 1 | 3 | 5 | 12 | 4 |
| 1 | 5 | 10 | 2 | 26 |
| 14 | 3 | 8 | NULL | NULL |
+---------+---------+---------+---------+---------+
Desired Output: numbers in ascending order.
+---------+---------+---------+---------+---------+
| Number1 | Number2 | Number3 | Number4 | Number5 |
+---------+---------+---------+---------+---------+
| 1 | 3 | 4 | 5 | 6 |
| 1 | 2 | 5 | 10 | 26 |
| 3 | 8 | 14 | NULL | NULL |
+---------+---------+---------+---------+---------+
JSON Approach: combines the columns into a JSON array but I still can't order correctly when in JSON format.
REPLACE ( CONCAT('[', LEFT(ColString1+ColString2,LEN(ColString1+ColString2) - 1), ']') ,';',',')
Any help will be greatly appreciated whether there is a way to order the xml or JSON string prior to entry. Happy to consider an alternative way if there is an easier solution.

You can use string_agg() and string_split():
select t.*, newstring
from t cross apply
(select string_agg(value, ',') order by (value) as newstring
from (select s1.value
from unnest(colstring1, ',') s1
union all
select s2.value
from unnest(colstring2, ',') s2
) s
) s;
That said, you should probably put your effort into fixing the data model. Storing numbers in strings is bad. Storing multiple values in a string is bad, bad. If the numbers are foreign references to other tables, that is bad, bad, bad, bad, bad.

While waiting for a DDL and sample data population, etc., here is a conceptual example for you. It is using XQuery and its FLWOR expression.
CTE does most of the heavy lifting:
Concatenates both columns values into one string. CONCAT() function protects against NULL values.
Converts it into XML data type.
Sorts XML elements by converting their values to int data type in the FLWOR expression.
Filters out XML elements with no legit values.
The rest is trivial.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, col1 VARCHAR(100), col2 VARCHAR(100));
INSERT INTO #tbl (col1, col2)
VALUES
('1;3;5;12;', '4;6;'),
('1;5;10;', '2;26;');
-- DDL and sample data population, end
DECLARE #separator CHAR(1) = ';';
;WITH rs AS
(
SELECT *
, CAST('<root><r><![CDATA[' +
REPLACE(CONCAT(col1, col2), #separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML).query('<root>
{
for $x in /root/r[text()]
order by xs:int($x)
return $x
}
</root>') AS sortedXML
FROM #tbl
)
SELECT ID
, c.value('(r[1]/text())[1]','INT') AS Number1
, c.value('(r[2]/text())[1]','INT') AS Number2
, c.value('(r[3]/text())[1]','INT') AS Number3
-- continue with the rest of the columns
FROM rs CROSS APPLY sortedXML.nodes('/root') AS t(c);
Output
+----+---------+---------+---------+
| ID | Number1 | Number2 | Number3 |
+----+---------+---------+---------+
| 1 | 1 | 3 | 4 |
| 2 | 1 | 2 | 5 |
+----+---------+---------+---------+

Related

Count string occurances within a list column - Snowflake/SQL

I have a table with a column that contains a list of strings like below:
EXAMPLE:
STRING User_ID [...]
"[""null"",""personal"",""Other""]" 2122213 ....
"[""Other"",""to_dos_and_thing""]" 2132214 ....
"[""getting_things_done"",""TO_dos_and_thing"",""Work!!!!!""]" 4342323 ....
QUESTION:
I want to be able to get a count of the amount of times each unique string appears (strings are seperable within the strings column by commas) but only know how to do the following:
SELECT u.STRING, count(u.USERID) as cnt
FROM table u
group by u.STRING
order by cnt desc;
However the above method doesn't work as it only counts the number of user ids that use a specific grouping of strings.
The ideal output using the example above would like this!
DESIRED OUTPUT:
STRING COUNT_Instances
"null" 1223
"personal" 543
"Other" 324
"to_dos_and_thing" 221
"getting_things_done" 146
"Work!!!!!" 22
Based on your description, here is my sample table:
create table u (user_id number, string varchar);
insert into u values
(2122213, '"[""null"",""personal"",""Other""]"'),
(2132214, '"[""Other"",""to_dos_and_thing""]"'),
(2132215, '"[""getting_things_done"",""TO_dos_and_thing"",""Work!!!!!""]"' );
I used SPLIT_TO_TABLE to split each string as a row, and then REGEXP_SUBSTR to clean the data. So here's the query and output:
select REGEXP_SUBSTR( s.VALUE, '""(.*)""', 1, 1, 'i', 1 ) extracted, count(*) from u,
lateral SPLIT_TO_TABLE( string , ',' ) s
GROUP BY extracted
order by count(*) DESC;
+---------------------+----------+
| EXTRACTED | COUNT(*) |
+---------------------+----------+
| Other | 2 |
| null | 1 |
| personal | 1 |
| to_dos_and_thing | 1 |
| getting_things_done | 1 |
| TO_dos_and_thing | 1 |
| Work!!!!! | 1 |
+---------------------+----------+
SPLIT_TO_TABLE https://docs.snowflake.com/en/sql-reference/functions/split_to_table.html
REGEXP_SUBSTR https://docs.snowflake.com/en/sql-reference/functions/regexp_substr.html

How to ORDER BY Alphanumeric values in SQL specific columns

create table Employee(id int, Registration_no varchar(50),Name varchar(50))
insert into #Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into #Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into #Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into #Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into #Employee values(5,'DLW/TTC/19/8','RITESH')
insert into #Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into #Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into #Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into #Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into #Employee values(10,'DLW/TTC/19/10','ROSHNI')
select * from Employee
Hello I have the table given above.
Actually am facing problem while am trying to order this table's column (Registration_no)
So kindly help me to ORDER it according to its (Registration_no) column
Its not matter that how the other columns are arranged. I just want my Registration_no column to be arranged in the specific order like this
Registration_no
DLW/TTC/19/1
DLW/TTC/19/2
DLW/TTC/19/3
DLW/TTC/19/4
DLW/TTC/19/5
DLW/TTC/19/6
DLW/TTC/19/7
DLW/TTC/19/8
DLW/TTC/19/9
DLW/TTC/19/10
This will sort by the digits to the right of the last / in the Registration_No string. I'm only including the SortColumn in the result set so you can see the values. You can omit it from your query.
SELECT
e.*,
CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER) AS SortColumn
FROM #Employee AS e
ORDER BY
CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER)
Results:
+----+-----------------+---------+------------+
| id | Registration_no | Name | SortColumn |
+----+-----------------+---------+------------+
| 3 | DLW/TTC/19/1 | RUPAK | 1 |
| 2 | DLW/TTC/19/2 | RAJEEV | 2 |
| 1 | DLW/TTC/19/3 | RAMESH | 3 |
| 4 | DLW/TTC/19/4 | RAMLAAL | 4 |
| 9 | DLW/TTC/19/5 | SHRISTI | 5 |
| 6 | DLW/TTC/19/6 | HRITIK | 6 |
| 8 | DLW/TTC/19/7 | RUPALI | 7 |
| 5 | DLW/TTC/19/8 | RITESH | 8 |
| 7 | DLW/TTC/19/9 | ROSHAN | 9 |
| 10 | DLW/TTC/19/10 | ROSHNI | 10 |
+----+-----------------+---------+------------+
The SortColumn functions first REVERSE the string, then use CHARINDEX to find the position from the end of the string of the last occurrence of /, then take that number -1 from the right side of the original column (-1 to exclude the / itself).
You can use reverse function together with charindex function
SELECT e.*, cast( reverse(substring(reverse(Registration_no),1,
charindex('/',reverse(Registration_no),1) -1 ) ) as int ) as nr
FROM employee e
ORDER BY nr;
Demo
The main principle is extracting the pieces and converting them to a numerical value, such as integer, in the tail part of the string values. It's easier to operate from the beginning with substring function to this extraction provided reverse function is used to make read the string reversely. And in this case we need to determine the position of the first delimiter(/) by contribution of charindex function. All those functions exist since the version 2008.
If the pattern at the end of Registration_no is always like /X or /XX then:
select * from Employee
order by
case left(right(Registration_no, 2), 1)
when '/' then
left(Registration_no, len(Registration_no) - 1) + '0' + right(Registration_no, 1)
else Registration_no
end
See the demo.
Although I dont like the way the number is extracted, this is how it can be done
select cast(substring(registration_no, charindex('/', registration_no, len(registration_no) -3) + 1, 3) as int),
* from Employee
order by 1
I would suggest you order it on the frontend using regex assuming that you are wanting to order it for display purpose.
How about this.
select *
from Employee
order by LEFT(Registration_no,PATINDEX('%[0-9]%',Registration_no)-1)-- alpha sort
, CONVERT(INT,REPLACE(SUBSTRING(Registration_no,PATINDEX('%[0-9]%',Registration_no),PATINDEX('%[0-9]%',Registration_no)),'/', '')) -- number sort
The first thing you'll notice as you try to order by the Registration_no is that it will be ordered alphabetically due to the nature of the string contents of the column of type varchar. So the correct way to do it is to convert the last two parts of the reg no into numbers and use them in an order by clause. (in this case we can use only the last part since the 2nd last is always 19)
Doing a bit of search I found this function 'Parsename' which has a usage in replication scenarios as it splits the SQL object schema name into its forming parts, so we can use it here (as long as the reg no parts doesn't exceed 4 parts "the SQL objects maximum parts")
So this will work in that case in SQL Server (T-SQL):
SELECT *
FROM Employee
order by cast(Parsename(replace(Registration_no,'/','.'),1) as int)
More info here
Thanks
Try this query.
create table #Employee(id int, Registration_no varchar(50),Name varchar(50))
insert into #Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into #Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into #Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into #Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into #Employee values(5,'DLW/TTC/19/8','RITESH')
insert into #Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into #Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into #Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into #Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into #Employee values(10,'DLW/TTC/19/10','ROSHNI')
select * from #Employee
order by Registration_no
id Registration_no Name
----------- -------------------------------------------------- --------------------------------------------------
3 DLW/TTC/19/1 RUPAK
10 DLW/TTC/19/10 ROSHNI
2 DLW/TTC/19/2 RAJEEV
1 DLW/TTC/19/3 RAMESH
4 DLW/TTC/19/4 RAMLAAL
9 DLW/TTC/19/5 SHRISTI
6 DLW/TTC/19/6 HRITIK
8 DLW/TTC/19/7 RUPALI
5 DLW/TTC/19/8 RITESH
7 DLW/TTC/19/9 ROSHAN

SQL Sort Numeric Strings After Split

I currently have char values in a table column which are in the format "IS-" and then 1 to 5 numbers, a possible period with either 2 numbers or a letter following the period.
Examples are, IS-1, IS-12, IS-123, IS-123.11, IS-123.a.
I need to split the string so that I grab only the number part, sort the strings ASC, and the bring the strings back together the way they were.
Explanation. I have the following set of values, IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a. As you can see, because IS-1 comes before IS-8 they are sorting out of numerical order.
Any idea where to begin? I was thinking of using CASE, but I'm not really sure how to proceed.
Thanks.
Do string functions in your ORDER BY to remove only the number. Something like this should work:
SELECT col
FROM table
ORDER BY CAST(CASE WHEN ISNUMERIC(SUBSTRING(col,4,20)) = 1
THEN SUBSTRING(col,4,20)
ELSE LEFT(SUBSTRING(col,4,20),CHARINDEX('.',SUBSTRING(col,4,20),0)-1)
END AS NUMERIC)
This will first remove the IS- and check if the rest of the string is a number. If it is, it will leave the decimal digits, otherwise it will remove the . and the following alpha characters.
This is assuming your intended ordering in the case of numeric decimal places would be:
IS-123.A
IS-123.1
IS-123.2
If you don't care about what's after the decimal/period, then simply:
ORDER BY CAST(LEFT(SUBSTRING(col,4,20),CHARINDEX('.',SUBSTRING(col,4,20),0)-1) AS NUMERIC)
If I understand you correctly, this might help you:
DECLARE #mockup TABLE(ID INT IDENTITY,YourExample VARCHAR(100));
INSERT INTO #mockup VALUES
('IS-1, IS-12, IS-123, IS-123.11, IS-123.a.')
,('IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a');
WITH Splitted AS
(
SELECT *
,CAST('<x>' + REPLACE(m.YourExample,',','</x><x>') + '</x>' AS XML) AS SplitAtComma
FROM #mockup AS m
)
,NumberExtracted AS
(
SELECT s.ID
,part.value('text()[1]','nvarchar(max)') AS OnePart
,CAST('<y>' + REPLACE(REPLACE(part.value('text()[1]','nvarchar(max)'),'.','-'),'-','</y><y>') + '</y>' AS XML).value('/y[2]/text()[1]','int') AS TheNumber
FROM Splitted AS s
CROSS APPLY s.SplitAtComma.nodes('/x') AS A(part)
)
SELECT *
FROM NumberExtracted
ORDER BY ID,TheNumber;
The first CTE uses a string-split via XML to get all values within the original string (btw: never store comma separated values!).
The second CTE will use the same approach to extract the number, typesafe as INT.
You can use this in an ORDER BY finally.
The result:
+----+-----------+-----------+
| ID | OnePart | TheNumber |
+----+-----------+-----------+
| 1 | IS-1 | 1 |
+----+-----------+-----------+
| 1 | IS-12 | 12 |
+----+-----------+-----------+
| 1 | IS-123 | 123 |
+----+-----------+-----------+
| 1 | IS-123.11 | 123 |
+----+-----------+-----------+
| 1 | IS-123.a. | 123 |
+----+-----------+-----------+
| 2 | IS-870.a | 870 |
+----+-----------+-----------+
| 2 | IS-871.a | 871 |
+----+-----------+-----------+
| 2 | IS-872.a | 872 |
+----+-----------+-----------+
| 2 | IS-1170 | 1170 |
+----+-----------+-----------+
| 2 | IS-1171 | 1171 |
+----+-----------+-----------+
| 2 | IS-1172 | 1172 |
+----+-----------+-----------+
| 2 | IS-1173 | 1173 |
+----+-----------+-----------+
| 2 | IS-1174 | 1174 |
+----+-----------+-----------+
IF OBJECT_ID(N'tempdb..##table1', N'U') IS NOT NULL
DROP TABLE ##table1;
create table ##table1(col1 varchar(20))
declare #query as nvarchar(max)
declare #var1 as varchar(max)='IS-1, IS-12, IS-123, IS-123.11, IS-123.a.,IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a.'
set #var1=replace(#var1,',','''),(''')
set #var1='('''+#var1+''')'
set #var1=replace(#var1,' ','')
set #query='insert into ##table1 values'+#var1
EXEC sp_executesql #query
IF OBJECT_ID(N'tempdb..##table2', N'U') IS NOT NULL
DROP TABLE ##table2;
select * into ##table2 from ##table1 order by cast(replace(replace(replace(col1,'IS-',''),'.a.',''),'.a','') as float)
declare #results varchar(max)
select #results = coalesce(#results + ', ', '') + convert(varchar(12),col1) from ##table2
select #results
DROP TABLE ##table1
DROP TABLE ##table2

Teradata SQL select string of multiple capital letters in a text field

Any help would be much appreciated on figuring out how to identify Acronyms within a text field that has mixed upper and lower case letters.
For example, we might have
"we used the BBQ sauce on the Chicken"
I need my query to SELECT "BBQ" and nothing else in the cell.
There could be multiple capitalized string per row
The output should include the uppcase string.
Any ideas are much appreciated!!
This is going to be kind of ugly. I tried to use REGEXP_SPLIT_TO_TABLE to just pull out the all caps words, but couldn't make it work.
I would do it by first using strtok_split_to_table, so each word will end up in it's own row.
First, some dummy data:
create volatile table vt
(id integer,
col1 varchar(20))
on commit preserve rows;
insert into vt
values (1,'foo BAR');
insert into vt
values (2,'fooBAR');
insert into vt
values(3,'blah FOO FOO blah');
We can use strtok_split_to_table on this:
select
t.*
from table
(strtok_split_to_table(vt.id ,vt.col1,' ')
returns
(tok_key integer
,tok_num INTEGER
,tok_value VARCHAR(30)
)) AS t
That will split each value into separate rows, using a space as a delimiter.
Finally, we can compare each of those values to that value in upper case:
select
vt.id,
vt.col1,
tok_key,
tok_num,
tok_value,
case when upper(t.tok_value) = t.tok_value (CASESPECIFIC) then tok_value else '0' end
from
(
select
t.*
from table
(strtok_split_to_table(vt.id ,vt.col1,' ')
returns
(tok_key integer
,tok_num INTEGER
,tok_value VARCHAR(30)
)) AS t
) t
inner join vt
on t.tok_key = vt.id
order by id,tok_num
Taking our lovely sample data, you'll get:
+----+-------------------+---------+---------+-----------+-------------+
| id | col1 | tok_key | tok_num | tok_value | TEST_OUTPUT |
+----+-------------------+---------+---------+-----------+-------------+
| 1 | foo BAR | 1 | 1 | foo | 0 |
| 1 | foo BAR | 1 | 2 | BAR | BAR |
| 2 | fooBAR | 2 | 1 | fooBAR | 0 |
| 3 | blah FOO FOO blah | 3 | 1 | blah | 0 |
| 3 | blah FOO FOO blah | 3 | 2 | FOO | FOO |
| 3 | blah FOO FOO blah | 3 | 3 | FOO | FOO |
| 3 | blah FOO FOO blah | 3 | 4 | blah | 0 |
+----+-------------------+---------+---------+-----------+-------------+
Defining acronyms as all uppercase words with 2 to 5 characters with a '\b[A-Z]{2,5}\b' regex:
WITH cte AS
( -- using #Andrew's Volatile Table
SELECT *
FROM vt
-- only rows containing acronyms
WHERE RegExp_Similar(col1, '.*\b[A-Z]{2,5}\b.*') = 1
)
SELECT
outkey,
tokenNum,
CAST(RegExp_Substr(Token, '[A-Z]*') AS VARCHAR(5)) AS acronym -- 1st uppercase word
--,token
FROM TABLE
( RegExp_Split_To_Table
( cte.id,
cte.col1,
-- split before an acronym, might include additional characters after
-- [^A-Z]*? = any number of non uppercase letters (removed)
-- (?= ) = negative lookahead, i.e. check, but don't remove
'[^A-Z]*?(?=\b[A-Z]{2,5}\b)',
'' -- defaults to case sensitive
) RETURNS
( outKey INT,
TokenNum INT,
Token VARCHAR(30000) -- adjust to match the size of your input column
)
) AS t
WHERE acronym <> ''
I am not 100% sure what are you trying to do but I thing you have many options. I.e.:
Option 1) check if the acronym (like BBQ) exist in the string (basic syntax)
SELECT CHARINDEX ('BBQ',#string)
In this case you would need a table of all know acronyms you want to check for and then loop through each of them to see if there is a match for your string and then return the acronym.
DECLARE #string VARCHAR(100)
SET #string = 'we used the BBQ sauce on the Chicken'
create table : [acrs]
--+--- acronym-----+
--+ BBQ +
--+ IBM +
--+ AMD +
--+ ETC +
--+----------------+
SELECT acronym FROM [acrs] WHERE CHARINDEX ([acronym], #string ) > 0)
This should return : 'BBQ'
Option 2) load up all the upper case characters into a temp table etc. for further logic and processing. I think you could use something like this...
DECLARE #string VARCHAR(100)
SET #string = 'we used the BBQ sauce on the Chicken'
-- make table of all Upper case letters and process individually
;WITH cte_loop(position, acrn)
AS (
SELECT 1, SUBSTRING(#string, 1, 1)
UNION ALL
SELECT position + 1, SUBSTRING(#string, position + 1, 1)
FROM cte_loop
WHERE position < LEN(#string)
)
SELECT position, acrn, ascii(acrn) AS [ascii]
FROM cte_loop
WHERE ascii(acrn) > 64 AND ascii(acrn) < 91 -- see the ASCII table for all codes
This would return table like this:

Get rows where value is not a substring in another row

I'm writing recursive sql against a table that contains circular references.
No problem! I read that you can build a unique path to prevent infinite loops. Now I need to filter the list down to only the last record in the chain. I must be doing something wrong though. -edit I'm adding more records to this sample to make it more clear why just selecting the longest record doesn't work.
This is an example table:
create table strings (id int, string varchar(200));
insert into strings values (1, '1');
insert into strings values (2, '1,2');
insert into strings values (3, '1,2,3');
insert into strings values (4, '1,2,3,4');
insert into strings values (5, '5');
And my query:
select * from strings str1 where not exists
(
select * from strings str2
where str2.id <> str1.id
and str1.string || '%' like str2.string
)
I'd expect to only get the last records
| id | string |
|----|---------|
| 4 | 1,2,3,4 |
| 5 | 5 |
Instead I get them all
| id | string |
|----|---------|
| 1 | 1 |
| 2 | 1,2 |
| 3 | 1,2,3 |
| 4 | 1,2,3,4 |
| 5 | 5 |
Link to sql fiddle: http://sqlfiddle.com/#!15/7a974/1
My problem was all around the 'LIKE' comparison.
select * from strings str1
where not exists
(
select
*
from
strings str2
where
str2.id <> str1.id
and str2.string like str1.string || '%'
)