两部分问题:
在生成MySql的交叉表结果时,Distinct
调用似乎不起作用......或者我错过了其他内容?我在几列中得到了相同的ClassName
。即“MDC(介绍)”。
:SQLFiddle中的现有示例会产生结果(虽然不正确),但是当移动到托管的MySql时,它会失败并显示错误:
#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 'el
FROM EnrollmentsTblx
GROUP BY AutoNum' at line 1
SQL:
SET @sql = NULL;
SELECT
GROUP_CONCAT(
DISTINCT
CONCAT(
' GROUP_CONCAT((CASE ClassName when ', CHAR(39),
ClassName, CHAR(39),
' then ', CHAR(39), DateCompleted, CHAR(39), ' else NULL END)) AS `',
ClassName, '`'
)
) INTO @sql
FROM EnrollmentsTbl;
SET @sql = CONCAT('SELECT AutoNum, UserName, ', @sql, '
FROM EnrollmentsTbl
GROUP BY AutoNum, UserName');
SELECT @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Schems:
SET NAMES 'UTF8';
CREATE TABLE `EnrollmentsTbl` (
`AutoNum` INTEGER PRIMARY KEY,
`UserName` VARCHAR(50),
`SubmitTime` DATETIME,
`ClassName` VARCHAR(50),
`ClassDate` DATETIME,
`ClassTime` VARCHAR(50),
`Enrolled` BOOLEAN,
`WaitListed` BOOLEAN,
`Instructor` VARCHAR(50),
`DateCompleted` DATETIME,
`Completed` BOOLEAN,
`EnrollmentsMisc` VARCHAR(50),
`Walkin` BOOLEAN
) CHARACTER SET 'UTF8';
INSERT INTO `EnrollmentsTbl`(`AutoNum`,`UserName`,`SubmitTime`,`ClassName`,`ClassDate`,`ClassTime`,`Enrolled`,`WaitListed`,`Instructor`,`DateCompleted`,`Completed`,`EnrollmentsMisc`,`Walkin`)
VALUES(1,'John',NULL,'MDC (Intro)','2004-06-27 00:00:00',NULL,TRUE,FALSE,'Phil','2004-06-27 00:00:00',TRUE,NULL,FALSE),
(2,'Bob',NULL,'MDC (Intro)','2004-06-27 00:00:00',NULL,TRUE,FALSE,'Phil','2004-06-27 00:00:00',TRUE,NULL,FALSE),
(3,'Robert',NULL,'MDC (Intro)','2004-06-27 00:00:00',NULL,TRUE,FALSE,'Phil','2004-06-27 00:00:00',TRUE,NULL,FALSE),
(4,'John','2010-08-04 06:11:10','HIPAA (Employee)','2010-08-04 00:00:00','6:12 AM',TRUE,FALSE,'On-line','2010-08-04 06:11:10',TRUE,NULL,FALSE),
(5,'Debbie',NULL,'MDC (Intro)','2003-04-19 14:53:55',NULL,TRUE,FALSE,'devore','2003-04-19 14:53:55',TRUE,NULL,FALSE),
(6,'Jeff',NULL,'MDC (Intro)','2003-03-29 14:26:23',NULL,TRUE,FALSE,'','2003-03-29 14:26:23',TRUE,NULL,FALSE),
(7,'Tom',NULL,'Firehouse (Incident)','2004-07-13 00:00:00',NULL,TRUE,FALSE,'Shannon','2004-07-13 00:00:00',TRUE,NULL,FALSE),
(8,'Janet','2016-06-30 14:02:05','MDC (On-Line)','2016-06-30 00:00:00','2:02 PM',TRUE,FALSE,'On-line','2016-06-30 14:02:05',TRUE,NULL,FALSE);
小提琴屏幕截图:
我在Access数据库中使用SQL作为SQL:
TRANSFORM DateCompleted
SELECT UserName
FROM EnrollmentsTbl
GROUP BY UserName
ORDER BY UserName
PIVOT ClassName
期望的结果如下所示:
UserName MDC (Intro) HIPAA (Employee) Firehouse (Incident)
-------- ----------- ---------------- --------------------
John 6-27-2004 10-4-2006 8-6-2005
Bob 6-27-2004
Robert 6-27-2004 8-6-2005
Debbie 4-19-2003
Jeff 11-25-2006
Tom 7-13-2004
Janet 11-25-2006
答案 0 :(得分:1)
您的字符串在每个引号之前都有一个转义\
。
为了证明这一点,我将它转储到文本编辑器(MySQL Workbench)中,在创建表格后很明显。我为查找和替换做了一个ctrl-H,(\'到了'),并且能够执行准备好的stmt并获得结果集。
在系统(或shell或各种编程语言)之间移动数据时,这是一个常见问题。我还注意到数据末尾有一些\n
。
此外,DISTINCT适用于所有列(不是每个列)。
在两列输出上如此明显会导致以下容易:
class student
------- ----------
ABC Drew
ABC Barlay
查看mysql replace()
函数,或者:
SELECT
GROUP_CONCAT(
DISTINCT
CONCAT(
' GROUP_CONCAT((CASE ClassName when \'',
ClassName,
'\' then \'',DateCompleted,'\' else NULL END)) AS `',
ClassName, '`'
)
) INTO @sql
FROM EnrollmentsTbl;
SET @sql = CONCAT("SELECT AutoNum, UserName, ", @sql, " FROM EnrollmentsTbl GROUP BY AutoNum, UserName");
select @sql;
呈现:
SELECT AutoNum, UserName, GROUP_CONCAT((CASE ClassName when 'MDC (Intro)' then '2004-06-27 00:00:00' else NULL END)) AS `MDC (Intro)`, GROUP_CONCAT((CASE ClassName when 'HIPAA (Employee)' then '2010-08-04 06:11:10' else NULL END)) AS `HIPAA (Employee)`, GROUP_CONCAT((CASE ClassName when 'MDC (Intro)' then '2003-04-19 14:53:55' else NULL END)) AS `MDC (Intro)`, GROUP_CONCAT((CASE ClassName when 'MDC (Intro)' then '2003-03-29 14:26:23' else NULL END)) AS `MDC (Intro)`, GROUP_CONCAT((CASE ClassName when 'Firehouse (Incident)' then '2004-07-13 00:00:00' else NULL END)) AS `Firehouse (Incident)`, GROUP_CONCAT((CASE ClassName when 'MDC (On-Line)' then '2016-06-30 14:02:05' else NULL END)) AS `MDC (On-Line)` FROM EnrollmentsTbl GROUP BY AutoNum, UserName
-- Drew used above
像逃脱序列方面的魅力一样工作。
有关为什么在concat()
上使用双引号的一点点了解,好吧,使用单引号导致@sql
的prev值使用\
转义其单引号因此可能会导致系统出现1064错误。因此,如果将字符串放在一起的第二部分,你可能已经无家可归了。
始终暂停并查看步骤之间的字符串,以查看状态是什么状态,以及未执行的操作。
现在谈谈你的DISTINCT数据问题(那是关于堆栈的新问题,而不是这里)
答案 1 :(得分:0)
这似乎是我得到的最接近期望的结果,唯一的问题是它返回一个计数而不是完成的日期:
SELECT `UserName`,
COUNT(
CASE
WHEN `ClassName`='MDC (Intro)'
THEN `DateCompleted`
ELSE NULL
END
) AS 'MDC',
COUNT(
CASE
WHEN `ClassName`='HIPAA(Employee)'
THEN `DateCompleted`
ELSE NULL
END
) AS 'HIPAA',
COUNT(
CASE
WHEN `ClassName`='Firehouse (Incident)'
THEN `DateCompleted`
ELSE NULL
END
) AS 'Firehouse'
FROM EnrollmentsTbl
GROUP BY `UserName`;
示例来自:MySQL pivot table
答案 2 :(得分:0)
不像我想要的那样动态,但根据需要进行了格式化。
解决:
SELECT `UserName`,
MAX(IF(`ClassName`='MDC (Intro)', `DateCompleted`, NULL)) AS 'MDC',
MAX(IF(`ClassName`='HIPAA (Employee)', `DateCompleted`, NULL)) AS 'HIPAA',
MAX(IF(`ClassName`='MDC (On-Line)', `DateCompleted`, NULL)) AS 'MDC-OL',
MAX(IF(`ClassName`='Firehouse (Incident)', `DateCompleted`, NULL)) AS 'Fierhouse'
FROM EnrollmentsTbl
GROUP BY `UserName`;
工作示例: SQLFiddle