Фильтровать данные по строкам в Oracle

В таблице tab1 есть данные, как показано ниже.

Col1   Col2  Message (Value can be concatenation of multi messages string after "Hello there" can vary)
-----------------------------------------------------------
I1     L1    Message1|Message2|Hello there D1,D2,D3
I2     L2    Message1|MessageN|Hello there D3,D4,D1
I3     L3    Hello there D3,D5
I4     L4    Message3|Message4
I5     L5    Hello there DN,DN+1

Мне нужно выбрать только записи со строкой «Привет!» и никаких других сообщений, таких как Сообщение 1,2 .. N и т. д. (должны быть выбраны только 3-я и 5-я записи)

Может ли кто-нибудь помочь с эффективным способом сделать это? Я пробую, как показано ниже, но это не дает желаемого результата.

select * from tab1 t1 where message like '%Hello there%' 
and not exists (select 1 from tab1 t2 where t1.col1=t2.col1 and t1.col2 =t2.col2 and ???)

🤔 А знаете ли вы, что...
СУБД Oracle поддерживает многозадачность, что позволяет обрабатывать множество запросов одновременно.


2
51
4

Ответы:

Вот почему вы не получаете никакого результата:

and not exists (select 1 from tab1 t2 where t1.col1=t2.col1 and t1.col2 =t2.col2 and ???)

Вы выбираете цифру 1; это утверждение всегда будет истинным, а это значит, что оно всегда будет существовать. Поскольку вы хотите выбрать сообщения, когда они «не существуют», они не получат никаких данных.


Судя по предоставленной вами информации, вам нужны только записи, начинающиеся с «Привет». В этом случае вам нужно просто заменить подобный запрос с «%Hello there%» на «Hello there%».

select * from tab1 t1 where message like 'Hello there%'

Этот запрос выберет все записи, в которых данные поля сообщения начинаются с «Привет».


Решено

Найдите строки, содержащие только один термин (т. е. без разделителя терминов), которые начинаются с нужной фразы:

SELECT *
FROM   tab1
WHERE  message LIKE 'Hello there%'
AND    message NOT LIKE '%|%'

или, возможно, менее эффективно:

SELECT *
FROM   tab1
WHERE  REGEXP_LIKE(message, '^Hello there[^|]*$')

Что для примера данных:

CREATE TABLE tab1 (Col1, Col2, Message) AS
SELECT 'I1', 'L1', 'Message1|Message2|Hello there D1,D2,D3' FROM DUAL UNION ALL
SELECT 'I2', 'L2', 'Message1|MessageN|Hello there D3,D4,D1' FROM DUAL UNION ALL
SELECT 'I3', 'L3', 'Hello there D3,D5' FROM DUAL UNION ALL
SELECT 'I4', 'L4', 'Message3|Message4' FROM DUAL UNION ALL
SELECT 'I5', 'L5', 'Hello there DN,DN+1' FROM DUAL UNION ALL
SELECT 'I6', 'L6', 'Hello there DN,DN+1|Message6' FROM DUAL;

Оба вывода:

COL1 COL2 СООБЩЕНИЕ я3 Л3 Привет, D3, D5. I5 Л5 Здравствуйте, DN, DN+1

рабочий пример


where instr(message, 'Hello there') = 1 and instr(message, '|') = 0

тоже сделаю работу