Использование SQL LIKE и IN вместе
Есть ли способ использовать LIKE и IN вместе?
Я хочу добиться чего-то подобного.
SELECT * FROM tablename WHERE column IN ('M510%', 'M615%', 'M515%', 'M612%');
Итак, в основном я хочу иметь возможность сопоставить столбец с кучей разных строк. Есть ли другой способ сделать это с одним запросом или мне придется перебирать массив строк, которые я ищу?
Ответы
Ответ 1
Вы можете сделать это в одном запросе путем объединения отдельных LIKE с ORs:
SELECT * FROM tablename
WHERE column LIKE 'M510%'
OR column LIKE 'M615%'
OR column LIKE 'M515%'
OR column LIKE 'M612%';
Просто помните, что такие вещи, как LIKE и per-row, не всегда хорошо масштабируются. Если ваша таблица, вероятно, увеличится, вы можете захотеть добавить другой столбец в свою таблицу, чтобы сохранить первые четыре символа поля независимо.
Это дублирует данные, но вы можете гарантировать, что оно будет оставаться неизменным с помощью триггеров вставки и обновления. Затем поместите индекс в этот новый столбец, и ваши запросы станут:
SELECT * FROM tablename WHERE newcolumn IN ('M510','M615','M515','M612');
Это приводит к тому, что стоимость калькуляции доходит до той точки, где это необходимо (когда данные изменяются), а не каждый раз, когда вы его читаете. Фактически, вы могли бы пойти еще дальше, и ваш новый столбец будет логическим, указывая, что это один из четырех специальных типов (если эта группа специальных предложений будет изменяться нечасто). Тогда запрос будет еще быстрее:
SELECT * FROM tablename WHERE is_special = 1;
Этот компромисс требований к хранению для скорости - полезный трюк для больших баз данных - как правило, дисковое пространство дешево, CPU grunt ценен, а данные читаются гораздо чаще, чем написано. Перемещая калькуляцию затрат на этап записи, вы амортизируете затраты на все чтения.
Ответ 2
Как насчет использования подстроки с IN.
select * from tablename where substring(column,1,4) IN ('M510','M615','M515','M612')
Ответ 3
Вам нужно будет использовать несколько терминов LIKE
, связанных OR
.
Ответ 4
Используйте более длинную версию IN, которая является связкой OR.
SELECT * FROM tablename
WHERE column LIKE 'M510%'
OR column LIKE 'M615%'
OR column LIKE 'M515%'
OR column LIKE 'M612%';
Ответ 5
substr([column name],
[desired starting position (numeric)],
[# characters to include (numeric)]) in ([complete as usual])
Пример
substr([column name],1,4) in ('M510','M615', 'M515', 'M612')
Ответ 6
SELECT * FROM tablename
WHERE column IN
(select column from tablename
where column like 'M510%'
or column like 'M615%'
OR column like 'M515%'
or column like'M612%'
)
Ответ 7
Я попробовал другой способ
Скажите, что таблица имеет значения
1 M510
2 M615
3 M515
4 M612
5 M510MM
6 M615NN
7 M515OO
8 M612PP
9 A
10 B
11 C
12 D
Здесь cols с 1 по 8 действительны, а остальные из них недействительны
SELECT COL_VAL
FROM SO_LIKE_TABLE SLT
WHERE (SELECT DECODE(SUM(CASE
WHEN INSTR(SLT.COL_VAL, COLUMN_VALUE) > 0 THEN
1
ELSE
0
END),
0,
'FALSE',
'TRUE')
FROM TABLE(SYS.DBMS_DEBUG_VC2COLl('M510', 'M615', 'M515', 'M612'))) =
'TRUE'
То, что я сделал, это использование функции INSTR, которую я пытался найти, это значение в таблице соответствует любому из значений в качестве ввода. В случае, если это произойдет, он вернет ему индекс, т.е. Больше, чем ZERO. В случае, если значение таблицы не соответствует ни одному из входных данных, тогда оно вернет ZERO. Этот индекс я добавил, чтобы указать успешное совпадение.
Кажется, что он работает.
Надеюсь, что это поможет.
Ответ 8
Вы можете использовать подзапрос с подстановочными знаками:
SELECT 'Valid Expression'
WHERE 'Source Column' LIKE (SELECT '%Column' --FROM TABLE)
Или вы можете использовать одну строку:
SELECT 'Valid Expression'
WHERE 'Source Column' LIKE ('%Source%' + '%Column%')
Ответ 9
u может даже попробовать это
Функция
CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE @index int
SET @index = -1
WHILE (LEN(@text) > 0)
BEGIN
SET @index = CHARINDEX(@delimiter , @text)
IF (@index = 0) AND (LEN(@text) > 0)
BEGIN
INSERT INTO @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END
Запрос
select * from my_table inner join (select value from fn_split('M510', 'M615', 'M515', 'M612',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';
Ответ 10
Для идеально динамического решения это достигается путем объединения курсора и таблицы temp. С помощью этого решения вам не нужно знать начальную позицию или длину, и она может расширяться без необходимости добавлять OR в ваш SQL-запрос.
В этом примере предположим, что вы хотите выбрать идентификатор, данные и дату создания из таблицы, где определенный список текста находится внутри "Детали".
Сначала создайте таблицу FilterTable со строками поиска в столбце "Поиск".
Как задал вопрос стартер:
insert into [DATABASE].dbo.FilterTable
select 'M510' union
select 'M615' union
select 'M515' union
select 'M612'
Затем вы можете отфильтровать свои данные следующим образом:
DECLARE @DATA NVARCHAR(MAX)
CREATE TABLE #Result (ID uniqueIdentifier, Details nvarchar(MAX), Created datetime)
DECLARE DataCursor CURSOR local forward_only FOR
SELECT '%' + Search + '%'
FROM [DATABASE].dbo.FilterTable
OPEN DataCursor
FETCH NEXT FROM DataCursor INTO @DATA
WHILE @@FETCH_STATUS = 0
BEGIN
insert into #Result
select ID, Details, Created
from [DATABASE].dbo.Table (nolock)
where Details like @DATA
FETCH NEXT FROM DataCursor INTO @DATA
END
CLOSE DataCursor
DEALLOCATE DataCursor
select * from #Result
drop table #Result
Надеюсь, что это помогло