Как создать представление или таблицу из подготовленного отчета (выберите запрос)

Я пытаюсь создать View из следующего подготовленного оператора:

CREATE VIEW myview AS -- this line is not working
SELECT CONCAT(GROUP_CONCAT('SELECT ''', COLUMN_NAME,''' MyColumns, SUM(`', COLUMN_NAME,'`) Total FROM mydb.source_table' SEPARATOR '\n UNION ALL \n'),'\nORDER BY Total ASC')
INTO @sql
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'mydb' 
    AND TABLE_NAME   = 'source_table'
    AND COLUMN_NAME NOT IN ('ID', 'Name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DROP PREPARE stmt;

Я все еще запутался с обработкой синтаксиса group_concat.

Мне просто нужна помощь в том, как создать представление с помощью подготовленного выше оператора.

ОБНОВЛЕНИЕ 1: хранимая процедура

Как предложил @nbk, мне нужно создать 5 хранимых процедур в одном столбце, чтобы иметь возможность использовать данные и использовать их для запроса CREATE TABLE. Вот версия хранимой процедуры приведенных выше кодов.

CREATE DEFINER=`admin`@`%` PROCEDURE `sp_result`()
BEGIN
    SELECT CONCAT(GROUP_CONCAT('SELECT ''', COLUMN_NAME,''' MyColumns FROM mydb.source_table' SEPARATOR '\n UNION ALL \n'), '\n LIMIT 0, 1 \n')
    INTO @sql
    FROM  INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_SCHEMA = 'mydb' 
        AND TABLE_NAME   = 'source_table'
        AND COLUMN_NAME NOT IN ('ID', 'Name');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DROP PREPARE stmt;
END

Вот результат этой хранимой процедуры:

+-----------+
| MyColumns |
+-----------+
| Abc       |
+-----------+

Чтобы этот подход был мне полезен, я хочу, чтобы приведенный выше результат был одним из столбцов моего запроса CREATE TABLE:

Вот мои попытки, но безуспешно:

Первая попытка: отдельный запрос

CREATE TABLE my_table AS SELECT id, name, mydb.sp_result() FROM source_table; -- Error Code: 1305. FUNCTION project_x.best_vendor1_name does not exist

Вторая попытка: вставлен в последнюю часть хранимой процедуры

CREATE TABLE my_table AS SELECT @sql FROM source_table; -- no effect

Здесь я действительно не знаю, как CREATE TABLE с помощью хранимой процедуры возвращает данные.

ОБНОВЛЕНИЕ 2: иллюстрация инкапсуляции

CREATE DEFINER=`root`@`%` PROCEDURE `proc_column_sum`()
BEGIN
DROP TABLE IF EXISTS table2;
SELECT CONCAT('
    CREATE TABLE table2 AS (',GROUP_CONCAT('
        SELECT ''', COLUMN_NAME,''' MyColumns, SUM(`', COLUMN_NAME,'`) Total 
        FROM testdb.products ' 
        SEPARATOR '\n UNION ALL \n'), -- runtime syntax error somewhere here
    '\n ORDER BY Total ASC)') -- missing closing single quote right after ASC
INTO @sql
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'testdb' 
    AND TABLE_NAME   = 'products'
    AND COLUMN_NAME NOT IN ('ID', 'Name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DROP PREPARE stmt;
END

person RickyBelmont    schedule 01.08.2020    source источник
comment
это невозможно, вместо этого создайте хранимую процедуру   -  person nbk    schedule 01.08.2020
comment
@nbk Я рассматриваю ваше предложение как возможность изменить мой подход, если это действительно невозможно. Пожалуйста, посмотрите мое обновление (ОБНОВЛЕНИЕ 1) в моем вопросе, и мне нужна небольшая помощь с CREATE TABLE с использованием предложенной вами СОХРАНЕННОЙ ПРОЦЕДУРЫ.   -  person RickyBelmont    schedule 02.08.2020


Ответы (1)


Вы должны поместить CREATE TABLE в подготовленный оператор.

в этом примере временная таблица используется только в демонстрационных целях

CREATE DEFINER=`root`@`%` PROCEDURE `proc_column_sum`()
BEGIN
SELECT 
CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS (',GROUP_CONCAT('SELECT ''', COLUMN_NAME,''' MyColumns, SUM(`', COLUMN_NAME,'`) Total FROM testdb.products ' SEPARATOR '\n UNION ALL \n'),'\nORDER BY Total ASC)')
INTO @sql
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'testdb' 
    AND TABLE_NAME   = 'products'
    AND COLUMN_NAME NOT IN ('ID', 'Name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DROP PREPARE stmt;
END

ты называешь это тогда

call proc_column_sum();
SELECT * FROM table2

Но при таком подходе вам придется каждый раз вызывать процедуру для получения новейших данных.

Я не могу понять, что пошло не так в вашем запросе

CREATE DEFINER=`root`@`%` PROCEDURE `proc_column_sum`()
BEGIN
DROP TABLE IF EXISTS table2;
SELECT CONCAT('
    CREATE TABLE IF NOT EXISTS table2 AS (',GROUP_CONCAT('
    SELECT ''', COLUMN_NAME,''' MyColumns, SUM(`', COLUMN_NAME,'`) Total 
    FROM testdb.products ' 
    SEPARATOR '\n UNION ALL \n')
    ,'\nORDER BY Total ASC)')
INTO @sql
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'testdb' 
    AND TABLE_NAME   = 'products'
    AND COLUMN_NAME NOT IN ('ID', 'Name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DROP PREPARE stmt;
END
person nbk    schedule 02.08.2020
comment
Могу ли я использовать CREATE TABLE вместо CREATE TEMPORARY TABLE? Во-вторых, я получаю какую-то ошибку во время выполнения и все еще пытаюсь разобраться в синтаксисе. Я уверен, что правильно понял ваш код. - person RickyBelmont; 02.08.2020
comment
Вот ошибка, которую я получаю: Код ошибки: 1064. У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, на предмет правильного синтаксиса для использования рядом с «UNION ALL SELECT» Sed quidem aspernatur quisquam ut. Поставщик, SUM(`Sed quidem a' в строке 2 - person RickyBelmont; 02.08.2020
comment
да, вы используете таблицу, но вы должны сначала ее удалить. у вас странные имена столбцов, и вы допустили ошибку при передаче кода, чтобы отлаживать все, что вы можете сделать, от подготовки до выбора @sql; так что вы видите дырку и исправляете ее в коде, если есть проблема - person nbk; 02.08.2020
comment
Я правильно получаю group_concat при запуске @sql. Я думаю, что эта ошибка исходит где-то из-за новой инкапсуляции CREATE TABLE. Приведенный выше код не возвращает синтаксическую ошибку во время разработки, вместо этого он возвращает ошибку near 'UNION ALL во время выполнения. Я собираюсь предоставить обновление 2 выше, чтобы проиллюстрировать инкапсуляцию кодов. - person RickyBelmont; 03.08.2020
comment
Я обновил вопрос (ОБНОВЛЕНИЕ 2), чтобы проиллюстрировать мою версию инкапсуляции, и прокомментировал некоторые предполагаемые источники ошибок. - person RickyBelmont; 03.08.2020
comment
group_concat в порядке. Я мог видеть текст, и он отлично работает. На этот раз я пытаюсь увидеть concat text во время выполнения, чтобы проверить синтаксис, но я не знаю, как это сделать? - person RickyBelmont; 03.08.2020
comment
Я не могу понять, что не так с вашей попыткой, я взломал свою и отформатировал ее, как вашу, но все равно работает, выдает ошибки, но я не могу понять, почему - person nbk; 03.08.2020
comment
См. fiddle (создана фальшивая таблица продуктов, напечатан текст встроенного запроса, подготовленный оператор прокомментирован ) - похоже, что построенный текст SQL синтаксически неверен. - person RickyBelmont; 03.08.2020
comment
Нет, это не имеет ничего общего с синтаксисом, проблема в том, что mysql 5.7 не позволяет такого рода вещи, в mysql 8 он работает без проблем. у mariadb тоже нет с этим проблем - person nbk; 03.08.2020
comment
да! Я согласен. Я попробовал ваш код с mysql 8. он работает! Однако, можете ли вы проверить эту конкретную часть вашего кода ,'\nORDER BY Total ASC)'), сразу после ASC отсутствует одинарная кавычка, и я подозреваю, что 8.0 игнорирует эту незначительную ошибку, а 5.7 - нет. - person RickyBelmont; 04.08.2020
comment
Я подумываю об обновлении MySQL до 8.0. Разумно ли это делать сейчас? - person RickyBelmont; 04.08.2020
comment
Теперь он работает с версией 8.0 и не сталкивался с какими-либо проблемами. Можете ли вы опубликовать свой ответ здесь Создать таблицу в инструкции по подготовке MySQL чтобы я мог отметить ответ и закрыть дело. - person RickyBelmont; 04.08.2020