You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL动态行转列在自有表中失效,请求技术排查

动态行转列时出现MySQL 1064语法错误排查

问题概况

尝试将自有表行转列时触发1064语法错误,但参考的动态转列逻辑在测试表中可正常运行。本次仅使用tbl_members_contacts表(主键为MemberID+ContactTypeID组合外键)进行转置操作。

表结构与数据

-- phpMyAdmin SQL Dump
-- version 4.9.7
-- Host: localhost:3306
-- Generation Time: Nov 17, 2022 at 02:53 PM
-- Server version: 10.3.22-MariaDB
-- PHP Version: 7.4.30

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `sssorth_events2`
--

-- --------------------------------------------------------

--
-- Table structure for table `tbl_members`
--

CREATE TABLE `tbl_members` (
  `MemberID` int(11) NOT NULL,
  `FirstName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `LastName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `tbl_members`
--

INSERT INTO `tbl_members` (`MemberID`, `FirstName`, `LastName`) VALUES
(1, 'Olav', 'Jensen'),
(2, 'Thor', 'Hansen'),
(3, 'Henrik', 'Koppang');

-- --------------------------------------------------------

--
-- Table structure for table `tbl_members_contacts`
--

CREATE TABLE `tbl_members_contacts` (
  `MemberID` int(11) NOT NULL,
  `ContactTypeID` int(11) NOT NULL,
  `ContactInfo` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `ContactPref` tinyint(4) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `tbl_members_contacts`
--

INSERT INTO `tbl_members_contacts` (`MemberID`, `ContactTypeID`, `ContactInfo`, `ContactPref`) VALUES
(1, 1, 'olav_jensen@gmail.com', 0),
(1, 3, '+66 1845 5556', 0),
(2, 1, 'thor5567@hotmail.com', 0),
(2, 3, '+66 0850 555 244', 0),
(3, 1, 'henrikkoppang@gmail.com', 0),
(3, 3, '+66927745546', 0);

-- --------------------------------------------------------

--
-- Table structure for table `tbl_members_contacts_type`
--

CREATE TABLE `tbl_members_contacts_type` (
  `ContactTypeID` int(11) NOT NULL,
  `ContactType` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `tbl_members_contacts_type`
--

INSERT INTO `tbl_members_contacts_type` (`ContactTypeID`, `ContactType`) VALUES
(1, 'Email 1'),
(2, 'Email 2'),
(3, 'Phone 1'),
(4, 'Phone 2'),
(5, 'LINE'),
(6, 'WhatsAp'),
(7, 'WeChat'),
(8, 'Skype');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_members`
--
ALTER TABLE `tbl_members`
  ADD PRIMARY KEY (`MemberID`);

--
-- Indexes for table `tbl_members_contacts`
--
ALTER TABLE `tbl_members_contacts`
  ADD PRIMARY KEY (`MemberID`,`ContactTypeID`),
  ADD KEY `ContactTypeID` (`ContactInfo`),
  ADD KEY `ContactTypeID1` (`ContactTypeID`),
  ADD KEY `MemberID` (`MemberID`);

--
-- Indexes for table `tbl_members_contacts_type`
--
ALTER TABLE `tbl_members_contacts_type`
  ADD PRIMARY KEY (`ContactTypeID`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_members`
--
ALTER TABLE `tbl_members`
  MODIFY `MemberID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=286;

--
-- AUTO_INCREMENT for table `tbl_members_contacts_type`
--
ALTER TABLE `tbl_members_contacts_type`
  MODIFY `ContactTypeID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `tbl_members_contacts`
--
ALTER TABLE `tbl_members_contacts`
  ADD CONSTRAINT `tbl_members_contact_typeTable1` FOREIGN KEY (`ContactTypeID`) REFERENCES `tbl_members_contacts_type` (`ContactTypeID`);
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

报错的转置SQL代码

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when ContactTypeID = ''',
      ContactTypeID,
      ''' then ContactInfo end) ',
      ContactTypeID
    )
  ) INTO @sql
FROM
  tbl_members_contacts;
SET @sql = CONCAT('SELECT MemberID, ', @sql, ' 
                  FROM tbl_members_contacts 
                   GROUP BY MemberID');

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

错误信息

#   Time        Action  Message Duration / Fetch
1   15:30:46    3   SET @sql = NULL 0 row(s) affected   0.000 sec
2   15:30:46    3   SELECT
   GROUP_CONCAT(DISTINCT
     CONCAT(
       'max(case when ContactTypeID = ''',
       ContactTypeID,
       ''' then ContactInfo end) ',
       ContactTypeID
     )
   ) INTO @sql
 FROM
   tbl_members_contacts 1 row(s) affected   0.000 sec
3   15:30:46    3   SET @sql = CONCAT('SELECT MemberID, ', @sql, ' 
                   FROM tbl_members_contacts 
                    GROUP BY MemberID') 0 row(s) affected   0.000 sec
4   15:30:46    0   PREPARE stmt FROM @sql  Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1,max(case when ContactTypeID = '3' then ContactInfo end) 3 
                   F' at line 1 0.000 sec

问题原因与修复方案

原因分析

错误根源在于动态生成的列别名格式不合法:直接使用数字类型的ContactTypeID作为列别名,MySQL中以数字开头的标识符必须用反引号(`)包裹,否则会被解析为语法错误。

修复后的SQL代码

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when ContactTypeID = ''',
      ContactTypeID,
      ''' then ContactInfo end) `',
      ContactTypeID,
      '`'
    )
  ) INTO @sql
FROM
  tbl_members_contacts;
SET @sql = CONCAT('SELECT MemberID, ', @sql, ' 
                  FROM tbl_members_contacts 
                   GROUP BY MemberID');

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

关键修复点

在生成列别名的部分,给ContactTypeID添加反引号包裹:

'`', ContactTypeID, '`'

这确保MySQL将数字ID识别为合法的列名标识符,避免语法解析错误。

内容的提问来源于stack exchange,提问作者Lasse Staalung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:40:41