我有一个数据库,我将关键字分组到项目和与每个关键字相关的数据,然后我显示dataachids foreach项目,每个关键字一行,所有从同一个表“data”检索的列。我有4个表,关键字,项目,group_keywords和数据。 “keywords”仅存储关键字,“投影”项目名称,“group_keywords”为分配给该项目的关键字的关键字ID,“data”是foreach关键字的所有数据所在的位置,由关键字的外键标识.id,以及用于标识数据名称的名称列。
现在要检索关键字+项目的所有数据,我使用此查询:
SELECT * FROM `group_keywords`
INNER JOIN keywords on keywords.id = keyword_id
INNER JOIN data ON data.id = keywords.id
WHERE `group_id` = (SELECT `id` FROM `projects` WHERE `name` = 'ProjectName'
这给了我类似的东西
id group_id keyword_id id keyword id name value
12 5 52 52 absorption food 52 data_name_x1 6
12 5 52 52 absorption food 52 data_name_x2 8
12 5 52 52 absorption food 52 data_name_x3 26
12 5 52 52 absorption food 52 data_name_x4 2
...
但我想要的是:
id group_id keyword_id id keyword id data_name_x1 data_name_x2 data_name_x3 data_name_x4
12 5 52 52 absorption food 52 6 8 26 2
...
所以我可以轻松地为datagrids排序和使用分页,否则我不知道怎么做,因为在使用大数据集时我不能将所有内容转储到数组中,而是将数据过多。
这是架构:
-- --------------------------------------------------------
-- Table structure for table `keywords`
CREATE TABLE IF NOT EXISTS `keywords` (
`id` int(10) unsigned NOT NULL auto_increment,
`keyword` varchar(255) NOT NULL,
UNIQUE KEY `id` (`id`),
UNIQUE KEY `keyword` (`keyword`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=115386 ;
-- --------------------------------------------------------
-- Table structure for table `data`
CREATE TABLE IF NOT EXISTS `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
-- Table structure for table `projects`
--
CREATE TABLE IF NOT EXISTS `projects` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(100) NOT NULL,
`parent` varchar(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ;
-- --------------------------------------------------------
-- Table structure for table `group_keywords`
CREATE TABLE IF NOT EXISTS `group_keywords` (
`id` int(10) NOT NULL auto_increment,
`group_id` int(10) NOT NULL,
`keyword_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `group_id` (`group_id`,`keyword_id`),
KEY `keyword_id` (`keyword_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=119503 ;
-- --------------------------------------------------------
-- Constraints for table `data`
--
ALTER TABLE `data`
ADD CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- --------------------------------------------------------
-- Constraints for table `group_keywords`
--
ALTER TABLE `group_keywords`
ADD CONSTRAINT `group_keywords_ibfk_1` FOREIGN KEY (`keyword_id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
答案 0 :(得分:3)
此操作传统上称为“unpivot”,一些RDBMS支持它,但MySQL似乎不是其中之一。您有两个选择,在SQL中执行或在PHP中执行。在MySQL中,它看起来像这样的自联接(我不知道哪个字段符合你的ID字段,所以原谅我创建我自己的例子)。从性能角度来看,请确保索引ID和列名称,否则这些联接将进行爬网。
shapes
ID Name Value
1 Color Red
1 Shape Circle
... for more "columns"
2 Color Green
2 Shape Square
... for more "columns"
SELECT
A.ID,
B.Value as Color,
C.Value as Shape
... for more "columns"
FROM shapes A
LEFT JOIN shapes B ON B.ID = A.ID AND B.Name = 'Color'
LEFT JOIN shapes C ON C.ID = A.ID AND C.Name = 'Shape'
... for more "columns"
哪个应该网络我们(除非我的head-SQL-parser今晚错误运行):
ID Color Shape
1 Red Circle
2 Green Square
对于PHP版本,您不一定要加载数组,可以对其进行流式处理。按PK排序,然后向下设置属性。在伪代码中:
Set X to undefined
Get a Record
Check the ID property, if it's different than X, create a new object, set X to the new ID, and yield the previous object
Set the property of the object based on the "Name" column of our result
希望这有帮助!