sql с функцией <> и подстрокой - PullRequest
0 голосов
/ 14 мая 2011

Вывод запроса должен возвращать записи, в которых компания не равна 'CABS' ИЛИ ​​подстроке компании до пустого пространства (например, CABS NUTS). Название компании может быть CABS, COBS, CABST, CABS NUTS, CAB

SELECT * 
  FROM records 
 WHERE UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) <> 'CABS' 
    OR COMPANY <> 'CABS'

Но вышеупомянутый запрос возвращает CABS NUTS вместе с COBS, CAB.

Я пытался использовать "LIKE CABS", он выглядит нормально, но если название компании - "CAB", он не вернет "CABS" и CABS NUTS из-за подобного. Таким образом, как полностью исключено.

Может кто-нибудь предложить мне.

Ответы [ 6 ]

1 голос
/ 15 мая 2011

вполне может определить, какие из них вы хотите получить, но рассмотрели ли вы LIKE 'CABS %'

1 голос
/ 14 мая 2011
SELECT
  *
FROM
  Records
WHERE
  LEFT(Company, 4) <> 'CABS'
  AND Company <> 'CABS'

Примечание. При базовом сравнении строк TSQL регистр не учитывается

1 голос
/ 14 мая 2011

Итак, вам нужны все записи, в которых первые 4 символа поля Company не являются "CABS". Хорошо.

WHERE left(company, 4) != 'CABS'
0 голосов
/ 16 мая 2011

Проблема, с которой вы столкнулись, возникает из-за того, что результат SUBSTR равен нулю, если нет пробела.И благодаря логике трех значений результат some_var <> NULL равен NULL, а не TRUE, как вы могли ожидать.

И пример этого показан в следующем запросе:

with mytab as (
  select 1 as myval from dual union all
  select 2 as myval from dual union all
  select null as myval from dual
)
select *
from mytab
where myval = 1
union all
select *
from mytab
where myval <> 1

Этот пример вернет только две строки, а не три строки, которые вы могли бы ожидать.

Есть несколько способов переписать условие, чтобы оно игнорировало нулевой результат функции substr.Они перечислены ниже.Однако, как упомянул один из других респондентов, эти два условия необходимо объединить с помощью оператора AND, а не OR.

Во-первых, вы можете явно проверить, что в столбце есть пробел, используя наборУсловия ниже:

(INSTR(company,' ') = 0 or 
 UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) <> 'CABS') and 
COMPANY <> 'CABS'

Другой вариант - использовать функцию LNNVL.Это функция, о которой я узнал совсем недавно.Он возвращает TRUE из условия, когда результатом условия, предоставленного в качестве входного значения, является FALSE или NULL.

lnnvl(UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) = 'CABS') and 
      COMPANY <> 'CABS'

И еще один вариант (который, вероятно, был бы моим предпочтительным вариантом) - использовать функцию REGEXP_LIKE,Это просто, по сути и легко читается.

WHERE not regexp_like(company, '^CABS( |$)')
0 голосов
/ 15 мая 2011

Во-первых, я думаю, что вы должны использовать AND вместо OR в вашем сложном состоянии.

Во-вторых, вы можете упростить условие следующим образом:

WHERE UPPER(SUBSTR(company, 0, (INSTR(company || ' ',' ') - 1))) <> 'CABS' 

То есть часть company <> 'CABS' в этом случае не нужна.

0 голосов
/ 15 мая 2011
select * from records where company NOT IN (SELECT company 
FROM records 
WHERE UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) = 'CABS' 
OR COMPANY = 'CABS')

Я думаю, что это будет извлекать нужные записи из таблицы записей

RECORDS:

COMPANY
=====================
CAB
CABST
COBS
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...