Имея таблицу настроек Entity-Attribute Value, которая структурирована следующим образом (это из стороннего плагина, я не могу изменить дизайн базы данных):
Теперь я хочу создать таблицу, в которой data_id
будет идентификатором, а имена будут столбцами, а значения - их значениями. Тем не менее, каждый data_id
не имеет значения для каждого имени, поэтому я хочу, чтобы значение в результате было NULL (или пустым), если в исходной таблице нет значения для этого имени.
Теперь я написал PHP-скрипт, который генерирует для меня требуемый запрос:
$ihash = function($len = 10){
return substr(str_shuffle(str_repeat("abcdefghijklmnopqrstuvwxyz", 10)), 0, 10);
};
$columns = $wpdb->get_col("SELECT DISTINCT name FROM ".$wpdb->prefix."cf7_vdata_entry");
$fromselects = [];
$left_joins = [];
$wheres = [];
$used=[];
foreach($columns as $column) {
$m = $ihash();
while(in_array($m,$used)) {
$m = $ihash();
}
array_push($used,$m);
array_push($fromselects,"$m.value as `$column`");
$left_joins .= " LEFT JOIN wp_cf7_vdata_entry AS $m ON a.data_id = $m.data_id ";
array_push($wheres,"$m.name = '$column'");
}
$query = "SELECT a.data_id, ".implode(", ",$fromselects)."
FROM (SELECT DISTINCT data_id FROM wp_cf7_vdata_entry) AS a JOIN
".$left_joins."
WHERE ".implode(" AND ",$wheres);
Вот так выглядит сгенерированный запрос:
SELECT a.data_id,
vtddnqrdjy.value AS `foerderung`,
fwfyxgczvn.value AS `company`,
jwlpmnbepe.value AS `firstname`,
-- ... more fields
FROM (SELECT DISTINCT data_id
FROM wp_cf7_vdata_entry) AS a
JOIN wp_cf7_vdata_entry AS vtddnqrdjy
ON a.data_id = vtddnqrdjy.data_id
JOIN wp_cf7_vdata_entry AS fwfyxgczvn
ON a.data_id = fwfyxgczvn.data_id
JOIN wp_cf7_vdata_entry AS jwlpmnbepe
ON a.data_id = jwlpmnbepe.data_id
-- ... more joins
WHERE vtddnqrdjy.name = 'foerderung'
AND fwfyxgczvn.name = 'company'
AND jwlpmnbepe.name = 'firstname'
AND mloxjygcqp.name = 'lastname'
-- ... more fields
LIMIT 10
Таблица результатов сгенерирована правильно, но результат пуст:
Причина в том, что результаты, которые не имеют значений ВСЕХ столбцов, отфильтровываются, но вместо этого они должны иметь нулевые значения (имеющие ровно один результат для каждого data_id, существующего в таблице). Я думал о замене всех LEFT JOIN
с FULL OUTER JOIN
с (что должно быть подделано в MySQL), но это усложняет ситуацию и, вероятно, и без того плохая производительность будет крайне плохой. Как я мог решить это?