Подтвердить что ты не робот

Как использовать подобное с объединением в sql?

У меня есть 2 таблицы, скажем, таблица A и таблица B, и я хочу выполнить соединение, но условие соответствия должно быть там, где столбец из A 'похож на столбец из B, означающий, что все может прибыть до или после столбец в B:

например: если столбец в равен 'foo'. Тогда объединение будет соответствовать, если столбец в B либо: "fooblah", "somethingfooblah", либо просто "foo". Я знаю, как использовать подстановочные знаки в стандартном выражении, но смущаюсь при выполнении соединения. Имеет ли это смысл? Спасибо.

4b9b3361

Ответ 1

Использование INSTR:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON INSTR(b.column, a.column) > 0

Использование LIKE:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE '%'+ a.column +'%'

Используя LIKE, с CONCAT:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%')

Помните, что во всех параметрах вы, вероятно, захотите управлять значениями столбцов в верхнем регистре ПЕРЕД сравнением, чтобы убедиться, что вы получаете совпадения без учета чувствительности к регистру:

SELECT *
  FROM (SELECT UPPER(a.column) 'ua'
         TABLE a) a
  JOIN (SELECT UPPER(b.column) 'ub'
         TABLE b) b ON INSTR(b.ub, a.ua) > 0

Наиболее эффективным будет в конечном счете на выходе EXPLAIN.

JOIN оговорки идентичны написанию предложений WHERE. Синтаксис JOIN также упоминается как ANSI JOINs, поскольку они стандартизованы. Не-ANSI JOINs выглядят так:

SELECT *
  FROM TABLE a,
       TABLE b
 WHERE INSTR(b.column, a.column) > 0

Я не буду беспокоиться о примере, отличном от ANSI LEFT JOIN. Преимущество синтаксиса ANSI JOIN заключается в том, что он отделяет то, что объединяет таблицы вместе с тем, что на самом деле происходит в предложении WHERE.

Ответ 2

В MySQL вы можете попробовать:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

Конечно, это будет массово неэффективный запрос, потому что он выполнит полное сканирование таблицы.

Обновление: здесь доказательство


create table A (MYCOL varchar(255));
create table B (MYCOL varchar(255));
insert into A (MYCOL) values ('foo'), ('bar'), ('baz');
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo');
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar');
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');
+-------+------------------+
| MYCOL | MYCOL            |
+-------+------------------+
| foo   | fooblah          |
| foo   | somethingfooblah |
| foo   | foo              |
| bar   | barblah          |
| bar   | somethingbarblah |
| bar   | bar              |
+-------+------------------+
6 rows in set (0.38 sec)

Ответ 3

Если это то, что вам нужно делать часто... тогда вам может понадобиться денормализовать связь между таблицами A и B.

Например, при вставке в таблицу B вы можете записать ноль или более записей в таблицу сопоставления B в A, основанную на частичном отображении. Аналогично, изменения в любой таблице могут обновить эту связь.

Это зависит от того, как часто изменяются таблицы A и B. Если они довольно статичны, то удар по INSERT менее болезненен, чем повторные хиты на SELECT.

Ответ 4

Использование условных критериев в соединении определенно отличается от предложения Where. Мощность между таблицами может создавать различия между предложениями Joins и Where.

Например, использование условия Like в Outer Join будет содержать все записи в первой таблице, перечисленные в объединении. Использование того же условия в предложении Where неявно изменяет соединение на внутреннее соединение. Обычно запись должна присутствовать в обеих таблицах для выполнения условного сравнения в предложении Where.

Обычно я использую стиль, указанный в одном из предыдущих ответов.

tbl_A as ta
    LEFT OUTER JOIN tbl_B AS tb
            ON ta.[Desc] LIKE '%' + tb.[Desc] + '%'

Таким образом, я могу управлять типом соединения.

Ответ 5

Когда написание запросов с нашего сервера LIKE или INSTR (или CHARINDEX в T-SQL) занимает слишком много времени, поэтому мы используем LEFT, как в следующей структуре:

select *
from little
left join big
on left( big.key, len(little.key) ) = little.key

Я понимаю, что это может работать только с разными окончаниями запроса, в отличие от других предложений с "%" + b + "%", но достаточно и намного быстрее, если вам нужен только b+ '%'.

Другой способ оптимизировать его по скорости (но не по памяти) - создать столбец в "little", то есть "len (little.key)", в качестве "lenkey" и пользователя вместо этого в приведенном выше запросе.