#mysql #sql
#mysql #sql
Вопрос:
У меня есть 2 таблицы tblA и tblB. Теперь я хочу получить имя с помощью op_code.
tblA
op_code | date | num
------------------------------------------------
a | 03/01 | 34
b | 04/03 | 5556
c | 03/05 | 555
tblB
id | op_code | Name
------------------------------------------------
1 | a | Jet
2 | b,c | Mike
3 | d | Tom
Поскольку данные op_code в tblB представляют собой комбинированные данные, поэтому я пытаюсь написать sql, как показано ниже.
select a.*, b.*
from tblA a
LEFT JOIN tblB b on a.op_code in (SUBSTRING_INDEX(b.op_code, ',', 13))
Это не работает. Есть ли какие-либо предложения?
Комментарии:
1. Примечание: Если вы можете, нормализуйте данные и не используйте столбцы, которые имеют несколько значений, подобных этому. Если вы не можете, то приведенные ответы предоставляют решение.
Ответ №1:
Вы можете использовать FIND_IN_SET()
здесь:
SELECT a.*, b.*
FROM tblA a
LEFT JOIN tblB b
ON FIND_IN_SET(a.op_code, b.op_code) > 0;
Но, поскольку хранение данных CSV в ваших таблицах SQL рассматривается как плохая практика, поскольку это ненормализованные данные, вы должны рассматривать это только как временный обходной запрос. Гораздо лучшим планом было бы зафиксировать только одну запись для каждого op_code
отношения в таблице B.
Просто для развлечения, вот еще один способ написать свой запрос с помощью REGEXP
:
SELECT a.*, b.*
FROM tblA a
LEFT JOIN tblB b
ON b.op_code REGEXP CONCAT('[[:<:]]', a.op_code, '[[:>:]]');
Вот демонстрация для второй версии запроса:
ДЕМОНСТРАЦИЯ
Комментарии:
1. большое спасибо, Тим и Ник ~. просто вопрос, почему нельзя использовать IN (SUBSTRING_INDEX(b.op_code, ‘,’, 13))? означает ли это, что SUBSTRING_INDEX не получит результат ( ‘a’, ‘b’) ?
2.@kuehne
SUBSTRING_INDEX
может использоваться для разделенияb,c
на отдельные значения, но в целом он не может обрабатывать строку CSV произвольной длины.FIND_IN_SET
REGEXP
Для этого вам нужен or .