简体   繁体   中英

SQL: select unique substrings from the table by mask

There is a SQL table mytable that has a column mycolumn . That column has text inside each cell. Each cell may contain "this.text/31/" or "this.text/72/" substrings (numbers in that substrings can be any) as a part of string.

What SQL query should be executed to display a list of unique such substrings?

PS Of course, some cells may contain several such substrings.

And here are the answers for questions from the comments: The query supposed to work on SQL Server. The prefered output should contain the whole substring, not the numeric part only. It actually could be not just the number between first "/" and the second "/".

And it is varchar type (probably)

Example: mycolumn contains such values:

abcd/eftthis.text/31/sadflh adslkjh
abcd/eftthis.text/44/khjgb ljgnkhj this.text/447/lhkjgnkjh
ljgkhjgadsvlkgnl
uygouyg/this.text/31/luinluinlugnthis.text/31/ouygnouyg
khjgbkjyghbk

The query should display:

this.text/31/
this.text/44/
this.text/447/

Having a table named test with the following data:

COLUMN1
aathis.text/31/
this.text/1/
bbbthis.text/72/sksk

could this be what you are looking for?

select SUBSTR(COLUMN1,INSTR(COLUMN1,'this.text', 1 ),INSTR(COLUMN1,'/',INSTR(COLUMN1,'this.text', 1 )+10) - INSTR(COLUMN1,'this.text', 1 )+1) from test;

result:

this.text/31/
this.text/1/
this.text/72/

i see your problem:

Assume the same table as above but now with the following data:

this.text/77/
xxthis.text/33/xx
xthis.text/11/xxthis.text/22/x
xthis.text/1/x

The following might help you:

SELECT SUBSTR(COLUMN1, INSTR(COLUMN1,'this.text', 1 ,1), INSTR(COLUMN1,'/',INSTR(COLUMN1,'this.text', 1 ,1)+10) - INSTR(COLUMN1,'this.text', 1 ,1)+1) FROM TEST
UNION
SELECT CASE WHEN (INSTR(COLUMN1,'this.text', 1,2 ) >0) THEN 
       SUBSTR(COLUMN1, INSTR(COLUMN1,'this.text', 1,2 ), INSTR(COLUMN1,'/',INSTR(COLUMN1,'this.text', 1 ,2),2) - INSTR(COLUMN1,'this.text', 1,2 )+1) end FROM TEST;

it will generate the following result:

this.text/1/
this.text/11/
this.text/22/
this.text/33/
this.text/77/

The downside is that you need to add a select statement for every occurance you might have of "this.text". If you might have 100 "this.text" in the same cell it might be a problem.

How about using a recursive CTE:

CREATE TABLE #myTable
(
myColumn VARCHAR(100)
)

INSERT INTO #myTable
VALUES
    ('abcd/eftthis.text/31/sadflh adslkjh'),
    ('abcd/eftthis.text/44/khjgb ljgnkhj this.text/447/lhkjgnkjh'),
    ('ljgkhjgadsvlkgnl'),
    ('uygouyg/this.text/31/luinluinlugnthis.text/31/ouygnouyg'),
    ('khjgbkjyghbk')


;WITH CTE
AS
(
    SELECT MyColumn, 
    CHARINDEX('this.text/', myColumn, 0)  AS startPos,
    CHARINDEX('/', myColumn, CHARINDEX('this.text/', myColumn, 1) + 10) AS endPos
    FROM #myTable
    WHERE myColumn LIKE '%this.text/%'
    UNION ALL
    SELECT T1.MyColumn, 
    CHARINDEX('this.text/', T1.myColumn, C.endPos) AS startPos,
    CHARINDEX('/', T1.myColumn, CHARINDEX('this.text/', T1.myColumn, c.endPos) + 10) AS endPos
    FROM #myTable T1
    INNER JOIN CTE C
        ON C.myColumn = T1.myColumn
    WHERE SUBSTRING(T1.MyColumn, C.EndPos, 100) LIKE '%this.text/%'

)
SELECT DISTINCT SUBSTRING(myColumn, startPos, EndPos - startPos)
FROM CTE

SQL> select SUBSTR(column_name,1,9) from tablename;

column_name


this.text

SELECT REGEXP_SUBSTR(column_name,'this.text/[[:digit:]]+/') 
FROM table_name

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM