Запрос сводной таблицы MySQL с динамическим значением столбца усечения столбцов - PullRequest
1 голос
/ 21 октября 2019

Я пытаюсь динамически поворачивать пары ключ-значение в таблице ниже.

+-----------------+-----------------------------+-------+
| id | category   | name                        | value |
+-----------------+-----------------------------+-------+
|  1 | acme       | 2fa                         |   0   |      
|  2 | acme       | abc_processing_date         | today |        
|  3 | acme       | activate_new_approve_person |   1   |         
|  4 | acme       | activate_new_schdule        |   1   |
|  5 | acme       | additional_footer_for_person|  NULL |   
+-----------------+-----------------------------+-------+

При выполнении запроса ниже я получаю сообщение об ошибке

'-new-schedule,IFNULL(IF(z_tmp_admin_system_settings.name = 'additional_footer_fo' at line 1

Это разработано с использованием метода, описанного Тарином в Запрос сводной таблицы MySQL с динамическими столбцами .

SET SESSION group_concat_max_len = 100000;
SET @sql = '';

SELECT GROUP_CONCAT(DISTINCT
                    CONCAT(
                            'IFNULL(IF(z_tmp_admin_system_settings.name = ''',
                            name,
                            ''', value, NULL), NULL) AS ',
                            name
                        )
           )
INTO @sql
FROM z_tmp_admin_system_settings;
SET @sql = CONCAT('SELECT subdomain, ', @sql, ' FROM name GROUP BY subdomain');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Ответы [ 2 ]

1 голос
/ 21 октября 2019

Есть несколько проблем с вашим кодом - уменьшая гравитацию:

  • вам нужно выбрать from z_tmp_admin_system_settings, а не from name
  • , столбец для группировки называется category, а не subdomain
  • , поскольку принцип запроса заключается в использовании агрегации, вам нужны функции агрегирования для сгенерированных столбцов, такие как MAX();старые версии MySQL не допускают использования агрегатной функции для неагрегированных столбцов, но к 1013 *
  • это не то, к чему нужно привыкать, рекомендуется использовать имя столбцов с обратными галочками, если один изимя конфликтует с зарезервированным словом (это не так в ваших примерах данных, но, вероятно, оно не является исчерпывающим)
  • DISTINCT, вероятно, не требуется, если вы не дублировали name s для категории (вв этом случае не стесняйтесь добавлять его обратно к приведенному ниже коду)
  • Примечание: IFNULL(..., NULL) - это неоперационная

Код:

SET SESSION group_concat_max_len = 100000;
SET @sql = '';

SELECT GROUP_CONCAT(
    CONCAT('MAX(IF(z_tmp_admin_system_settings.name = ''', name, ''', value, NULL)) AS `', name, '`')
)
INTO @sql
FROM z_tmp_admin_system_settings;
SET @sql = CONCAT(
    'SELECT category, ', 
    @sql, 
    ' FROM z_tmp_admin_system_settings GROUP BY category'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Демонстрация на DB Fiddle :

| category | 2fa | abc_processing_date | activate_new_approve_person | activate_new_schdule | additional_footer_for_person |
| -------- | --- | ------------------- | --------------------------- | -------------------- | ---------------------------- |
| acme     | 0   | today               | 1                           | 1                    |                              |
0 голосов
/ 21 октября 2019

Похоже, у некоторых из ваших имен есть дефисы;один из них оканчивается на -new-schedule (хотя отправленные данные образца имеют activate_new_schedule - это точно?). Вы должны заключить имена в обратные кавычки, чтобы избежать использования этих имен при использовании их в качестве псевдонимов.

SELECT GROUP_CONCAT(DISTINCT
                    CONCAT(
                            'IFNULL(IF(z_tmp_admin_system_settings.name = ''',
                            name,
                            ''', value, NULL), NULL) AS `',
                            name,
                            '`'
                        )
           )
INTO @sql
FROM z_tmp_admin_system_settings;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...