Home > Net >  How to find a specific rows n in SQL Server table
How to find a specific rows n in SQL Server table

Time:01-12

I am trying to create a SQL query that shows me messages with text1 and text3. I do not want to show anything else. I can find text1 and text1 id 2, but because there are other messages from other sources I cannot use id. I would also rather have everything in same column instead of making 2 columns.

select 
    a.id,
    a.message as cur
    b.message as next
from 
    mytable as a
join 
    mytable as b on a.id = b.id - 2
where 
    a.message like '%text1%'

My table:

id source message
01 a text1
02 a text2
03 a text3
04 a text1
05 b herp
06 c derp
07 a text4
08 a text5
09 b derp
10 a text1
11 a text6
12 a text7

Output should be like:

message
text1
text3
text1
text5
text1
text7

or this is okay too, but I would prefer first one:

message message
text1 text3
text1 text5
text1 text7

CodePudding user response:

This can be done via LEAD analytic function as follows:

Query with a two-column result:

With CTE As (
Select [message], Lead([message], 2) Over (Order by id) As message_1
From Tbl
Where [source]='a' 
)
Select [message], message_1
From CTE
Where [message] Like '%text1%'

Result:

message message_1
text1 text3
text1 text5
text1 text7

Query with a single column result:

With CTE As (
Select [message], Lead([message], 2) Over (Order by id) As message_1
From Tbl
Where source='a' 
)
Select V.[message]
From CTE Cross Apply (VALUES([message]), (message_1)) As V([message])
Where CTE.[message] Like '%text1%'

Result:

message
text1
text3
text1
text5
text1
text7

CodePudding user response:

It's difficult to understand the question, but based on the additional explanations in the comments (... I want to search for instances of text1 and also find and include related message text 2 rows from source a ...), two possible approaches to get the expected results are ROW_NUMBER() and LEAD(). Note, that you need an additional APPLY operator with a VALUES table value constructor to unpivot the columns:

Table:

SELECT *
INTO MyTable
FROM (VALUES
  (01, 'a', 'text1'),
  (02, 'a', 'text2'),
  (03, 'a', 'text3'),
  (04, 'a', 'text1'),
  (05, 'b', 'herp'),
  (06, 'c', 'derp'),
  (07, 'a', 'text4'),
  (08, 'a', 'text5'),
  (09, 'b', 'derp'),
  (10, 'a', 'text1'),
  (11, 'a', 'text6'),
  (12, 'a', 'text7')
) v (id, source, message)

Statement with ROW_NUMBER() and a self-join:

; WITH cte AS (
   SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS rn
   FROM MyTable
   WHERE source = 'a'
)    
SELECT c.message
FROM cte a
JOIN cte b ON a.rn = b.rn - 2
CROSS APPLY (VALUES (1, a.message), (2, b.message)) c (rn, message)
WHERE a.message like '%text1%'
ORDER BY a.rn, c.rn

Statement with LEAD():

; WITH cte AS (
   SELECT *, LEAD(message, 2) OVER (ORDER BY id) AS message2
   FROM MyTable
   WHERE source = 'a'  
)    
SELECT c.message
FROM cte a
CROSS APPLY (VALUES (1, a.message), (2, a.message2)) c (rn, message)
WHERE a.message LIKE '%text1%'
ORDER BY a.id, c.rn

Result:

message
-------
text1
text3
text1
text5
text1
text7
  •  Tags:  
  • Related