我有3个表 - 事物,defs和信息(可怕的名字,但为了简单而大大减少了!)
信息
CREATE TABLE `info` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`thingid` bigint(10) NOT NULL DEFAULT '0',
`defid` bigint(10) NOT NULL DEFAULT '0',
`data` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `infodata_coufie_ix` (`thingid`,`defid`)
);
id | thingid | defid | data
1 | 1 | 1 | 1
1 | 1 | 2 | 25
1 | 2 | 1 | 0
1 | 2 | 3 | yellow
1 | 3 | 1 | 0
DEFS
CREATE TABLE `defs` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`datatype` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
id | name | datatype
1 | enabled | boolean
2 | size | numeric
3 | colour | string
事
CREATE TABLE `things` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
);
id | name
1 | bill
2 | terry
3 | nancy
我希望能够显示“事物”的“defs”值,因此结果表/视图会像
thingid | name | enabled | size | colour
1 | bill | true | 25 | null
2 | terry | false | null | yellow
3 | nancy | true | null | null
因此defs
中的行将成为列标题;与thingid
的列标题匹配的值将形成这些行的数据。
我很久以前就已经在SQL Server中做过这件事了,因为我的生活不记得怎么做了。我现在需要在MySql5中完成它。我一直在阅读http://www.artfulsoftware.com/infotree/queries.php以及各种SE文章,但我现在已经把自己搞得一团糟了,所以我实际上要问别人。
答案 0 :(得分:2)
SELECT i.thingid, t.name,
MAX(IF(d.name = "enabled", i.data, NULL)) enabled,
MAX(IF(d.name = "size", i.data, NULL)) size,
MAX(IF(d.name = "colour", i.data, NULL)) colour
FROM info i
JOIN defs d ON i.defid = d.id
JOIN things t ON i.thingid = t.id
GROUP BY i.thingid
答案 1 :(得分:1)
我的解决方案:
CREATE TABLE info
(`id` int, `thingid` int, `defid` int, `data` varchar(6))
;
INSERT INTO info
(`id`, `thingid`, `defid`, `data`)
VALUES
(1, 1, 1, '1'),
(1, 1, 2, '25'),
(1, 2, 1, '0'),
(1, 2, 3, 'yellow'),
(1, 3, 1, '0'),
(1, 1, 5, 'bad'),
(1, 1, 6, 2606),
(1, 3, 4, 'banana')
;
CREATE TABLE defs
(`id` int, `name` varchar(7), `datatype` varchar(7))
;
INSERT INTO defs
(`id`, `name`, `datatype`)
VALUES
(1, 'enabled', 'boolean'),
(2, 'size', 'numeric'),
(3, 'colour', 'string'),
(4, 'flavour', 'thing'),
(5, 'smell', 'essence'),
(6, 'line', 'numeric')
;
CREATE TABLE things
(`id` int, `name` varchar(5))
;
INSERT INTO things
(`id`, `name`)
VALUES
(1, 'bill'),
(2, 'terry'),
(3, 'nancy')
;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
' MAX(IF(d.name = ''',
d.name,
''', i.data, NULL)) AS ',
d.name
)
) INTO @sql
FROM info i join defs d on i.defid = d.id;
SET @sql = CONCAT('SELECT i.thingid, t.name, ',
@sql,
' FROM info i',
' JOIN defs d ON i.defid = d.id',
' JOIN things t ON i.thingid = t.id',
' GROUP BY i.thingid');
PREPARE statement FROM @sql;
EXECUTE statement;
请参阅小提琴:http://www.sqlfiddle.com/#!2/d481a/2
当您向defs
添加更多列,并为这些记录添加后续数据info
时,结果中会显示更多列,非匹配列中应为空值。