动态 mysql 数据透视表 table 失败

Dynamic mysql pivot table failing

CREATE TABLE `tUSER` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `id_number` varchar(20) NOT NULL,
  `first_names` varchar(100) NOT NULL,
  `last_name` varchar(100) NOT NULL
  PRIMARY KEY (`id`),
  INDEX( `id_number`, `first_names`, `last_name`)
)

CREATE TABLE `tPROFILE` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `tUSER_id` bigint(20) DEFAULT NULL,
  `tTYPES_id` bigint(20) DEFAULT NULL,
  `value` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_index` (`tUSER_id`,`tTYPES_id`),
  INDEX( `tUSER_id`, `tTYPES_id`, `value`)
)

CREATE TABLE `tTYPES` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `type` varchar(100) NOT NULL DEFAULT '',
  `description` varchar(255) NOT NULL,
  `deleted` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  FULLTEXT( `type`, `description`)
)

以上是需要从我获得 ID 号或手机号码时获取枢轴 table 的架构(CellphonetTYPES 中的记录 table)

我的静态枢轴有效,因为我填充了 table 并且知道类型

select tUSER.*,
  max(CASE WHEN tTYPES.type = 'msisdn' THEN tPROFILE.value ElSE 0 END) AS 'msisdn',
  max(CASE WHEN tTYPES.type = 'network' THEN tPROFILE.value ELSE 0 END) AS 'network',
  max(CASE WHEN tTYPES.type = 'points' THEN tPROFILE.value ELSE 0 END) AS 'points',
  max(CASE WHEN tTYPES.type = 'card number' THEN tPROFILE.value ELSE 0 END) AS 'card number',
  max(CASE WHEN tTYPES.type = 'gender' THEN tPROFILE.value ELSE 0 END) AS 'gender'
 from e1m_test.tUSER 
inner join e1m_test.tPROFILE on tPROFILE.tUSER_id = tUSER.id
inner join e1m_test.tTYPES on tPROFILE.tTYPES_id = tTYPES.id
where tUSER.id = 312

我需要一个动态数据透视查询,因为我不会总是知道类型 以下是我目前的努力,但它告诉我一个我无法解决的语法错误

SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT 
    CONCAT('max(CASE WHEN tTYPES.type="', 
    tTYPES.type, '" THEN tPROFILE.value ELSE 0 END) AS '
    , tTYPES.type))
INTO @sql
FROM
  tTYPES, tPROFILE;

SET @sql = CONCAT('select tUSER.*, ', @sql, ' 
    from tUSER 
    left join tPROFILE on tPROFILE.tUSER_id = tUSER.id
    left join tTYPES on tPROFILE.tTYPES_id = tTYPES.id
    where tUSER.id = 312');

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

错误

09:54:06    PREPARE stmt FROM @sql  Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'number,max(CASE WHEN tTYPES.type="gender" THEN tPROFILE.value ELSE 0 END) AS gen' at line 1  0.141 sec

欢迎任何帮助或指导

推测tTYPE中有类型与MySQL关键字冲突(例如number是语言关键字)。您需要使用反引号引用这些标识符。

进一步的建议:

  • 我不明白为什么在生成条件表达式的查询中需要 table tPROFILE;相应地,distinctgroup_concat()

    中似乎是不必要的
  • 我建议对字符串文字使用单引号而不是双引号 - 虽然这在 MySQL 中是允许的,但它偏离了 ANSI SQL 标准,因为没有附加值(你只需要正确转义嵌入的单引号)

  • group_concat()以内不需要concat();聚合函数愉快地接受参数列表,并将它们无缝地连接起来

所以:

SET @sql = NULL;
SELECT GROUP_CONCAT( 
    'MAX(CASE WHEN tTYPES.type=''', tTYPES.type, 
    ''' THEN tPROFILE.value ELSE 0 END) AS `', tTYPES.type, '`'
) INTO @sql
FROM tTYPES;

SET @sql = CONCAT('select tUSER.*, ', @sql, ' 
    from tUSER 
    left join tPROFILE on tPROFILE.tUSER_id = tUSER.id
    left join tTYPES on tPROFILE.tTYPES_id = tTYPES.id
    where tUSER.id = 312'
);

-- debug your query before running it!
-- SELECT @sql;           
           
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;