使用过程 MySQL 创建视图时出错

Error while creating a view with procedure MySQL

我在尝试使用过程创建视图时遇到问题。我必须这样做,因为我需要在 MySQL 中创建一个枢轴,将 table 的行转换为另一个的列。 查询效果很好,但是当我把它放在 "CREATE VIEW" 语句中时,它给了我错误。

这是带有 CREATE 视图的查询

CREATE VIEW `Untitled` AS 
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(IF(formazioni_persone.id_formazione = ',
      formazioni.id,
      ', true, false)) AS "',
      formazioni.titolo,'"'
    )
  ) INTO @sql
FROM formazioni;

SET @sql = CONCAT('SELECT persone.*, ', @sql, ' FROM persone INNER JOIN formazioni_persone ON persone.id = formazioni_persone.id_persona GROUP BY persone.id');

PREPARE stmt1 FROM @sql; 

EXECUTE stmt1; 

DEALLOCATE PREPARE stmt1;

没有 CREATE VIEW Untitled AS 的查询效果很好

没有 CREATE VIEW Untitled AS 的查询效果很好。我已经尝试在 CREATE VIEW 中创建一个 TEMP TABLE,但没有。也尝试过使用这样的分隔符,但什么都没有

DELIMITER $$ 
CREATE VIEW `Untitled` AS 
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(IF(formazioni_persone.id_formazione = ',
      formazioni.id,
      ', true, false)) AS "',
      formazioni.titolo,'"'
    )
  ) INTO @sql
FROM formazioni;

SET @sql = CONCAT('SELECT persone.*, ', @sql, ' FROM persone INNER JOIN formazioni_persone ON persone.id = formazioni_persone.id_persona GROUP BY persone.id');

PREPARE stmt1 FROM @sql; 

EXECUTE stmt1; 

DEALLOCATE PREPARE stmt1;
END $$ 
DELIMITER ;

错误:1064 - 您的 SQL 语法有误;查看与您的 MySQL 服务器版本对应的手册,了解在第 2 行 'SET @sql = NULL' 附近使用的正确语法,时间:0.082000s

VIEW 不是过程。 VIEW 只是一个 SELECT 语句,在定义 VIEW 时必须有固定的列。你不能创建一个也是过程的 VIEW。

抱歉,如果您需要数据透视表-table,您需要为查询中的每一列指定值。您不能创建 SELECT 查询或 VIEW 在发现潜在的未来值时动态添加更多列。

而且您无论如何都无法定义运行任意过程代码块的 VIEW。那需要一个程序。

您应该只使用已经在 MySQL - Rows to Columns

等问题中显示的解决方案

没有其他捷径或解决方法。

顺便说一句,所有 SQL数据库都有这个限制,不仅仅是MySQL。


回复你的问题:

I'm looking for a solution that doesn't require manual update of the query

数据透视表-table 查询在select-列表中的列数必须与您希望它return 的列数一样多。无法创建一个 SQL 查询来根据执行时读取的数据动态扩展列数。

您可以进行 return 所有数据的单个查询的唯一方法是不执行 pivot-table 查询,而是 return 行中的所有数据,而不是列。

SELECT p.*, f.titolo, pf.id_persona IS NOT NULL AS ha_formazioni
FROM persone AS p 
CROSS JOIN formazioni AS f
LEFT OUTER JOIN formazioni_persone AS fp ON fp.id_formazioni AND fp.id_persona = p.id

这将 return 每 formazionipersone 一行。然后您必须在您的应用程序中编写代码以遍历结果的所有行,并以您想要的方式格式化列中的数据。