Как получить «динамические» атрибуты, хранящиеся в нескольких строках, как обычные записи? - PullRequest
5 голосов
/ 02 апреля 2012

У меня есть система, построенная на реляционной базе данных MySQL, которая позволяет людям хранить детали "потенциальных клиентов". Кроме того, люди могут создавать свои собственные столбцы для хранения данных, а затем при добавлении новых учетных записей могут добавлять данные под них. Структура таблицы выглядит следующим образом:

ВЕДУЩИЕ - Я бы, Эл. адрес, user_id

АТРИБУТЫ - Я бы, attr_name, user_id

ATTR_VALUES - lead_id, attr_id, значение, user_id

Очевидно, что в этих таблицах «user_id» относится к таблице «Users», которая просто содержит людей, которые могут войти в систему.

Я пишу функцию для вывода сведений о потенциальной возможности, и в настоящее время я просто перетаскиваю основные детали потенциальной возможности в виде запроса, а затем проверяю каждое значение атрибута, связанное с этим потенциальной возможностью (объединяю таблицу атрибутов для получения имени), а затем присоединение массивов в PHP. Это немного грязно, и мне было интересно, есть ли способ сделать это в одном запросе SQL. Я немного читал о том, что называется «сводной таблицей», но я пытаюсь понять, как это работает.

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 4 ]

1 голос
/ 02 апреля 2012

Вы можете выполнить поворот в одном запросе, как показано ниже:

select l.id lead_id,
       l.email,
       group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone,
       ...
from leads l
left join attr_values v on l.id = v.lead_id
left join attributes a on v.attr_id = a.id
group by l.id

Вам нужно будет включить отдельное group_concat -обработанное поле для каждого атрибута, который вы хотите отобразить.

0 голосов
/ 23 сентября 2012

Я буду осторожен, предполагая, что пивот достигнет вашей цели упрощения.Pivot будет работать, только если ваше attr_name соответствует.Поскольку вы привязали к нему идентификатор пользователя, я предполагаю, что это не так.Кроме того, у вас будет несколько значений для одного attr_name.Боюсь, сводная таблица не даст результата, который вы ищете.

Я бы предложил разделить таблицы транзакций и отчетов.Имейте подпрограмму ETL, которая очистит (то есть сделает attr_name и attr_value) последовательными через перевод.Это сделает ваши отчеты более значимыми.

Таким образом, для немедленного вывода конечному пользователю PHP - лучшее, что вы можете сделать.Для создания отчетов сначала преобразуйте EAV в строку / столбец, прежде чем создавать отчеты по нему.

0 голосов
/ 02 апреля 2012

Что вы, вероятно, хотите от mysql - это сделать значение sql (attr_name в вашем случае) столбцом.Этот принцип называется сводная таблица (иногда также кросс-таблицы или кросс-таблицы запросов) и не поддерживается mysql.Не потому, что mysql недостаточен, а потому, что операция pivot не является операцией базы данных - результатом является не обычная таблица базы данных, а , а не , предназначенная для дальнейших операций с базой данных. Единственная цель операции сводки - презентация - поэтому она относится к уровню представления, а не к базе данных.

Таким образом, каждое решение попытки получить сводную таблицу из mysql всегда будет хакерским.Я рекомендую получить данные из базы данных в обычном формате, просто выполнив что-то вроде:

select *
from attr_values join attributes using on attr_id = attributes.id
    join leads on leads.id = lead_id

, а затем преобразуйте выходные данные базы данных в язык представления (PHP, JSP, Python или все, что вы используете).

0 голосов
/ 02 апреля 2012

Я бы посмотрел на эту ссылку . Это объясняет фундаментальный стержень:

«Сводная таблица» или «отчет кросс-таблицы» Характеристика SQL Функции: Выполнить без "if", "case" или "GROUP_CONCAT". Да, есть польза для операторы this ... "if" иногда вызывают проблемы при использовании в сочетание. Простой секрет, а также почему они работают почти Для всех баз данных есть следующие функции: sign (x) возвращает -1,0, +1 для значений x <0, x = 0, x> 0 соответственно abs (знак (x)) возвращает 0 если x = 0, 1, если x> 0 или x <0 1-abs (знак (x)) дополнения к выше, так как это возвращает 1, только если x = 0 </p>

Это также объясняет более простой способ поворота экзаменов. Может быть, это может пролить свет на это?

...