Как преобразовать нормализованный набор данных с помощью PHP?

Вот мои таблицы:

таблица пользователей

id   |   name
1    |   john
2    |   lucy

таблица user_accounts

id   |   user_id    |   account_name
1          2             lucy_lu
2          1             johndoe

таблица account_parameters

id   |  account_id  |  parameter_id   |  value
1           1              10             4000
2           1              11             1450
3           2              10             5000
4           2              11             1150

таблица параметров

id   |   parameter_value  |  parameter_name
10          height               Height
11          max_score            Max Score

Я хочу получить результат:

user_id | user_name | account_name |  Height  |  Max Score
1          john        johndoe        5000       1150
2          lucy        lucy_lu        4000       1450

Я искал «mysql генерировать столбцы с данными» и тому подобное, нашел много решений для 1 или 2 таблиц, но я не знаю, как реализовать их здесь. Я знаю, как выбирать статические поля с помощью объединений, но я не знаю, как выбрать «Высота» и «Макс. Оценка» в этом примере.

3

Решение

если ты должен сделать это с помощью SQL, затем использование PHP, который пишет SQL, кажется наименее тесно связанным подходом.

Сначала запросите таблицу параметров и сохраните ее в массиве.

Затем создайте строку запроса из трех частей, а средняя часть создается динамически.

SELECT
user_accounts.user_id          AS user_id,
user.name                      AS user_name,
user_accounts.account_name     AS account_name,

Повторите это для каждой записи в вашем массиве (который пришел из parameters).

    SUM(
CASE WHEN account_parameters.parameter_id = @param_id
THEN account_parameters.value
END
)   AS @param_name,

Использование PHP для подстановки значений @param_id и @param_name.

(Будьте осторожны с запятыми, они не нужны в последней строке SQL.)

FROM
account_parameters
INNER JOIN
user_accounts
ON  user_accounts.id = account_parameters.account_id
INNER JOIN
user
ON  user.id = user_accounts.user_id
GROUP BY
user_accounts.user_id,
user.name,
user_accounts.account_name

Замечания: В MySQL вам действительно нужно только GROUP BY user_accounts.user_id, но я не рекомендую абиспользуя эту функцию в целом.

Выполнение этого динамически созданного запроса должно изменить ваши результаты.

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

3

Другие решения

Так как я сделал что-то подобное, вот что для начала:

$parameters = array(
array("id" => 10, "parameter_value" => "height", "parameter_name" => "Height"),
array("id" => 11, "parameter_value" => "max_score", "parameter_name" => "Max Score")
); //fetch all parameters from your parameters table

//specify the table where the values are stored
$tableName = 'account_parameters';
//specify the column name in this table where the identifier for your data lies
$dataIdColumnName = 'account_id';

//set the first column up, which holds your datakey
$selectPivotFields = array("`".$tableName."`.`".$dataIdColumnName."`");

//loop over all parameters
if(is_array($parameters))
for($i=0;$i<count($parameters);$i++)
{
//build a part of your pivot query
$selectPivotFields[] = sprintf("MAX(IF(`%1$s`.`parameter_id` = '%2$d', `%1$s`.`value`, NULL)) AS `%3$s`", $tableName, $parameters[$i]['id'], $parameters[$i]['parameter_value']);
}

//build the actual query for readability i simplified it a little bit
$sql = sprintf("SELECT
%1$s
FROM
`%2$s`
WHERE
`%2$s`.`%3$s` = '%4$d'
GROUP BY
`%2$s`.`%3$s`
", implode(", ", $selectPivotFields), $tableName, $dataIdColumnName, $dataId);

//and execute your query with the prefered class
$result = execute($sql);

в основном, это тот же фон, чем ответ от MatBailie

2

По вопросам рекламы [email protected]