SQL: выбрать между разделителями с самими разделителями, вставить в другой столбец и удалить строку
Вместо одного столбца для каждой группы значений я создал один столбец с именем "data" и использовал HTML следующим образом:
<dt>Phone:</dt><dd>0 23 16/3 82 73 42 23</dd>
<dt>Phone:</dt><dd>0 21 61/81 26 73 13 22</dd>
<dt>Fax:</dt><dd>03 27/3 87 42 37 32</dd>
<dt>Website:</dt><dd>www.example.com</dd>
Теперь, я понял, это было не очень умно, и я сделал столбец для каждого значения. Мои новые имена столбцов "телефон", "phone2", "факс" и "веб-сайт".
Мне нужен код SQL, например, для выбора всех между разделителями <dt>Phone:</dt><dd>
а также </dd>
и сам разделитель, вставьте эту строку в столбец "телефон" и удалите эту строку в столбце "данные". Но мне нужно выбрать первую строку <dt>Phone:</dt><dd>0 23 16/3 82 73 42 23</dd>
не второй <dt>Phone:</dt><dd>0 21 61/81 26 73 13 22</dd>
,
Кто-нибудь может дать мне подсказку, как это сделать?
1 ответ
Для выбора данных между <dt>Phone:</dt><dd>
а также </dd>
Вы можете использовать SUBSTRING_INDEX.
Как это
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(data, '</dd>', 1), '<dt>Phone:</dt><dd>', -1) as phone,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Phone:</dt><dd>', -1), '</dd>', 1) as phone2,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Fax:</dt><dd>', -1), '</dd>', 1) as fax,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Website:</dt><dd>', -1), '</dd>', 1) as website
from data_col;
Обновить:
<dt>Phone:</dt>
не всегда в топе.
в случае, если в столбце "data" нет определенного порядка данных, попробуйте следующее:
SELECT
IF (temp.f_phone > 0, SUBSTR(data, temp.f_phone + LENGTH('<dt>Phone:</dt><dd>'), f_phone_end - temp.f_phone - LENGTH('<dt>Phone:</dt><dd>')), null) as PHONE_1,
IF (temp.s_phone > 0, SUBSTR(data, temp.s_phone + LENGTH('<dt>Phone:</dt><dd>'), s_phone_end - temp.s_phone - LENGTH('<dt>Phone:</dt><dd>')), null) as PHONE_2
from data_col dc
JOIN (
SELECT id, @f_phone:= LOCATE('<dt>Phone:</dt><dd>', data) as f_phone,
LOCATE('</dd>', data, @f_phone+1) f_phone_end,
@s_phone := LOCATE('<dt>Phone:</dt><dd>', data, @f_phone+1) as s_phone,
LOCATE('</dd>', data, @s_phone+1) as s_phone_end
from data_col) temp ON temp.id = dc.id;
Сначала найдите начальную позицию каждого возможного элемента (например, "телефон", "phone2") и позицию закрывающей метки. <\dd>
, А чем пользуетесь SUBSTR
от начальной позиции элемента + длина разделителя, с length = end_position - start_position - delimiter_length