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

Другие вопросы по тегам