2015-11-05 28 views
1

这是我的SQL表和数据。 http://sqlfiddle.com/#!9/effe2MySql将行写入列(但动态行)

CREATE TABLE IF NOT EXISTS `CustomValue` (
    `id` int(11) NOT NULL, 
    `customFieldId` int(11) NOT NULL, 
    `relatedId` int(11) NOT NULL, 
    `fieldValue` text COLLATE utf8_unicode_ci, 
    `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

INSERT INTO `CustomValue` (`id`, `customFieldId`, `relatedId`, `fieldValue`, `createdAt`) VALUES 
(1, 10, 4031, NULL, '2015-11-05 04:25:00'), 
(2, 14, 4031, '[email protected]', '2015-11-05 04:25:00'), 
(3, 13, 4031, '456', '2015-11-05 04:25:00'), 
(4, 16, 4031, '2015-11-09', '2015-11-05 04:25:00'), 
(5, 9, 4031, '456', '2015-11-05 04:25:00'), 
(6, 11, 4031, 'dsasda', '2015-11-05 04:25:00'), 
(7, 15, 4031, '1', '2015-11-05 04:25:00'); 

现在它是,

id customFieldId relatedId fieldValue   createdAt 
1 10     4031  (null)    November, 05 2015 04:25:00 
2 14     4031  [email protected] November, 05 2015 04:25:00 
3 13     4031  456    November, 05 2015 04:25:00 
4 16     4031  2015-11-09   November, 05 2015 04:25:00 
5 9     4031  456    November, 05 2015 04:25:00 
6 11     4031  dsasda    November, 05 2015 04:25:00 
7 15     4031  1     November, 05 2015 04:25:00 

我需要按relatedId和并得到最终的输出为1行每个relatedId。

这是参考表。

CREATE TABLE IF NOT EXISTS `CustomField` (
    `id` int(11) NOT NULL, 
    `customTypeId` int(11) NOT NULL, 
    `fieldName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `relatedTable` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `defaultValue` text COLLATE utf8_unicode_ci, 
    `sortOrder` int(11) NOT NULL DEFAULT '0', 
    `enabled` char(1) COLLATE utf8_unicode_ci DEFAULT '1', 
    `listItemTag` char(1) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `required` char(1) COLLATE utf8_unicode_ci DEFAULT '0', 
    `onCreate` char(1) COLLATE utf8_unicode_ci DEFAULT '1', 
    `onEdit` char(1) COLLATE utf8_unicode_ci DEFAULT '1', 
    `onView` char(1) COLLATE utf8_unicode_ci DEFAULT '1', 
    `listValues` text COLLATE utf8_unicode_ci, 
    `label` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `htmlOptions` text COLLATE utf8_unicode_ci 
) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

INSERT INTO `CustomField` (`id`, `customTypeId`, `fieldName`, `relatedTable`, `defaultValue`, `sortOrder`, `enabled`, `listItemTag`, `required`, `onCreate`, `onEdit`, `onView`, `listValues`, `label`, `htmlOptions`) VALUES 
(13, 1, 'HOMEEMAIL', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Home Email', ''), 
(9, 1, 'LANDPHONENO', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Land Phone No', ''), 
(10, 12, 'ABOUTME', 'people', '', 0, '1', NULL, '0', '1', '1', '1', NULL, 'About Me', ''), 
(11, 3, 'PHONENUMBER2', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Phone Number 2', ''), 
(14, 3, 'ALTERNATEEMAIL', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Alternate Email', ''), 
(15, 11, 'SCHOOLING?', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Schooling?', ''), 
(16, 4, 'JOINDATE', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Join Date', ''); 

最后的输出应该是,

relatedId | Alternate Email | Home Email | Join Date | Land Phone No | Phone Number 2 | Schooling? 
-------------------------------------------------------------------------------------------------- 
4031  | [email protected] | 456  | 2015-11-09| 456   | dsasda   | 1 

relatedId | Alternate Email | Home Email | Join Date | Land Phone No | Phone Number 2 | Schooling? | Interest 
-------------------------------------------------------------------------------------------------- 
4033  | [email protected] | 456  | 2015-11-09| 456   | dsasda   | 1 | Drawing 

的phpmyadmin的输出

enter image description here

+2

当你有'relatedId',该行应作为一个结果,对多个相同的值? – Smutje

+0

@Smutje请检查更新后的问题 – dev1234

+0

您正在尝试旋转表格:看看这个问题:http://stackoverflow.com/questions/7674786/mysql-pivot-table – AgeDeO

回答

1

你所需要的就是PIVOT行转换成列,但MySQL的不例如,有一个本地数据透视操作员,如SQL Server或Oracle。但是你可以使用CASE表达组通过做到这一点是这样的:

SELECT 
    v.relatedId, v.CreatedAt, 
    MAX(IF(f.fieldName = 'ABOUTME', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'ABOUTME', 
    MAX(IF(f.fieldName = 'ALTERNATEEMAIL', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'ALTERNATEEMAIL', 
    MAX(IF(f.fieldName = 'HOMEEMAIL', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'HOMEEMAIL', 
    MAX(IF(f.fieldName = 'JOINDATE', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'JOINDATE', 
    MAX(IF(f.fieldName = 'LANDPHONENO', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'LANDPHONENO', 
    MAX(IF(f.fieldName = 'PHONENUMBER2', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'PHONENUMBER2', 
    MAX(IF(f.fieldName = 'SCHOOLING?', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'SCHOOLING?' 
FROM customField AS f 
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId 
GROUP BY v.relatedId, v.CreatedAt; 

,并动态做它,你必须使用动态SQL这样做:

SET @Colvalues = NULL; 
SET @sql = NULL; 

SELECT 
    GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(f.fieldName = ''', 
     f.fieldName, ''', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS ', '''', f.fieldName , '''') 
) INTO @Colvalues 
FROM customField AS f 
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId; 


SET @sql = CONCAT('SELECT 
    v.relatedId, v.CreatedAt, ', @Colvalues , ' 
FROM customField AS f 
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId 
GROUP BY v.relatedId, v.CreatedAt;'); 

PREPARE stmt 
FROM @sql; 

EXECUTE stmt; 

需要注意的是:

  • 如果字段值为空,它将从默认值字段中设置值,那就是COALESCE(v.fieldValue, f.defaultValue)所做的。
  • 您可以通过添加一个WHERE v.fieldValue IS NOT NULL来消除NULL值,如Aboutname

这会给你:

enter image description here

+0

感谢您的输入。然而我没有得到任何结果的动态SQL解决方案,除了从phpmyadmin作为行的消息:1.顺便说一句,我是新的动态SQL。 – dev1234

+0

@ dev1234 - phpmyadmin告诉你什么?是否有任何错误返回? –

+0

没有错误返回。我拍了截图并更新了问题。请检查。结果不显示。 – dev1234