Я работаю над практической проблемой MySQL, которая включает поворот таблицы. Я хотел, чтобы запрос был как можно более общим, поэтому решил использовать динамическое вращение.

Ниже мой код:

/* Change depending on table names */
WITH t AS (SELECT OCCUPATION AS Header FROM OCCUPATIONS GROUP BY OCCUPATION 
       ORDER BY FIELD(OCCUPATION,'Doctor', 'Professor', 'Singer', 'Actor')),

     t2 AS (SELECT NAME As Entries, OCCUPATION As Header, 
           ROW_NUMBER() OVER(PARTITION BY OCCUPATION ORDER BY NAME) AS ID FROM OCCUPATIONS)

/* Dynamic pivoting code */
SELECT GROUP_CONCAT( CONCAT(' MAX(IF(Header = ''', t.Header ,''', Entries, NULL)) AS ',t.Header))
INTO @PivotQuery FROM t;

SET @PivotQuery = CONCAT(' SELECT ', @PivotQuery, ' FROM t2 GROUP BY ID');

PREPARE statement FROM @PivotQuery;
EXECUTE statement;
DEALLOCATE PREPARE statement;

Когда я выполняю это, я получаю эту ошибку. «ОШИБКА 1146 (42S02) в строке 12: Таблица« t2 »не существует»

Единственный способ заставить код работать - это сделать это так:

/* Change depending on table names */
WITH t AS (SELECT OCCUPATION AS Header FROM OCCUPATIONS GROUP BY OCCUPATION 
       ORDER BY FIELD(OCCUPATION,'Doctor', 'Professor', 'Singer', 'Actor'))
       
/* Dynamic pivoting code */
SELECT GROUP_CONCAT( CONCAT(' MAX(IF(Header = ''', t.Header ,''', Entries, NULL)) AS ',t.Header))
INTO @PivotQuery FROM t;

SET @PivotQuery = CONCAT(' SELECT ', @PivotQuery, ' FROM 
                         
                         /* Declared t2 here instead */
                         (SELECT NAME As Entries, OCCUPATION As Header, 
                          ROW_NUMBER() OVER(PARTITION BY OCCUPATION ORDER BY NAME) AS ID
                          FROM OCCUPATIONS)
                         /* End of Declaration */
                         
                         t2 GROUP BY ID');

PREPARE statement FROM @PivotQuery;
EXECUTE statement;
DEALLOCATE PREPARE statement;

Интересно, почему второй запрос не может вызвать t2, когда первый запрос может вызвать t? Кроме того, есть ли способ объявить t2 в начале, а не в середине предполагаемого общего кода? Спасибо!

0
schrodingerscat11 27 Фев 2021 в 05:07

1 ответ

Лучший ответ

Ладно, разобрался. Я не совсем понимаю, но CTE существует только во время запроса после него. Итак, для следующего запроса CTN t2 больше не существует. Вместо этого я решил использовать временные таблицы и получил то, что хотел. Вот код:

/* Change depending on table names */
CREATE TEMPORARY TABLE t AS 
    (SELECT NAME As Entries, OCCUPATION As Header, 
     ROW_NUMBER() OVER(PARTITION BY OCCUPATION ORDER BY NAME) AS ID
     FROM OCCUPATIONS);

WITH o AS (SELECT OCCUPATION AS Header FROM OCCUPATIONS GROUP BY OCCUPATION 
       ORDER BY FIELD(OCCUPATION,'Doctor', 'Professor', 'Singer', 'Actor'))
       
/* Dynamic pivoting code */
SELECT GROUP_CONCAT( CONCAT(' MAX(IF(Header = ''', o.Header ,''', Entries, NULL)) AS ',o.Header))
INTO @PivotQuery FROM o;

SET @PivotQuery = CONCAT(' SELECT ', @PivotQuery, ' FROM t GROUP BY ID');

PREPARE statement FROM @PivotQuery;
EXECUTE statement;
DEALLOCATE PREPARE statement;
0
schrodingerscat11 27 Фев 2021 в 16:13