Вот еще одна попытка.Я полностью изменяю вашу архитектуру здесь, но вы все равно можете найти ее полезной.
Несортированный набор значений
Для этого ответа я предполагаю, что порядок столбцов НЕ важен (вы в основномхранение набора значений в них).Я думаю, что лучшая архитектура для этого - хранить каждое значение в отдельной строке.Это значительно упрощает запросы и изменения (отсюда мой комментарий к вашему вопросу).
В этом случае я бы создал новую таблицу, которая выглядит следующим образом:
ID ValueSet
1 value1
1 value2
1 value3
2 value1
Дляпреобразовав две таблицы в эту, вы можете использовать следующий запрос:
SELECT ID,C1 AS `ValueSet` FROM `tab1` WHERE C1 IS NOT NULL
UNION SELECT ID,C2 FROM `tab1` WHERE C2 IS NOT NULL
UNION SELECT ID,C3 FROM `tab1` WHERE C3 IS NOT NULL
UNION SELECT ID,C4 FROM `tab1` WHERE C4 IS NOT NULL
UNION SELECT ID,C1 FROM `tab2` WHERE C1 IS NOT NULL
Таким образом удаляются значения NULL, а значения tab2 добавляются по мере необходимости.
Снова обратите внимание, что выпотерять порядок столбцов здесь.
Набор отсортированных значений
Если порядок важен, вы все равно можете включить при создании с помощью этого измененного запроса:
SELECT ID,C1 AS `ValueSet`,'1' AS 'Order' FROM `tab1` WHERE C1 IS NOT NULL
UNION SELECT ID,C2,'2' FROM `tab1` WHERE C2 IS NOT NULL
UNION SELECT ID,C3,'3' FROM `tab1` WHERE C3 IS NOT NULL
UNION SELECT ID,C4,'4' FROM `tab1` WHERE C4 IS NOT NULL
UNION SELECT ID,C1,'5' FROM `tab2` WHERE C1 IS NOT NULL
Затем, если вам нужен отсортированный набор значений для идентификатора1, вы можете использовать:
SELECT ValueSet FROM `myNewTable` WHERE ID = '1' ORDER BY Order ASC;
, что даст:
value1
value2
value3