MRE
CREATE TABLE `publications` (
`id` mediumint unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `publications` (`title`)
VALUES
('Publication #1'),
('Publication #2'),
('Publication #3'),
('Publication #4'),
('Publication #5'),
('Publication #6');
CREATE TABLE `keywords_relation` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`keyword_id` mediumint unsigned DEFAULT NULL,
`parent_id` mediumint unsigned DEFAULT NULL,
`parent_type` tinyint unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `keywords_relation` (`keyword_id`,`parent_id`,`parent_type`)
VALUES
(1,1,0),
(2,1,0),
(4,1,0),
(1,2,0),
(4,2,0),
(6,3,0),
(6,4,0),
(6,2,0),
(2,1,0),
(3,4,0),
(3,5,4),
(4,6,4),
(4,2,4),
(5,1,4),
(5,3,4),
(6,4,4),
(6,6,4);
#1,2,4
http://sqlfiddle.com/#!9/c1a035e/25
Problem
I want to retrieve all publications that belong to a certain research line, but the relationship is defined by common keywords. That's it, if a publication has one or more keywords in common with the research line, we say that the publication is part of that research line.
I need help tyding up the following relation.As of now it takes 3 different queries to retrieve the related publications and I bet it can be done in less & in a tidier way but I am completely lost.
Structure:
I have the following tables (simplified):
publications
Research publications. columnsid
,title
lines
Research Lines. columnsid
,title
keywords
Keywords. columnsid
,name
keywords_relations
A pivot table that contains many-to-many relationships between keywords, publications and research lines. columnsid
,keyword_id
,parent_id
,parent_type
Where keyword_relations
.parent_id
is 0 for research lines and 4 for publications.
Current approach
1.) Get the research line's keywords
1
in this case is the ID of a certain research line. As a result of this query I get an array of keyword ids.
select `keywords`.`id` from `keywords`
inner join `keywords_relation` on `keywords`.`id` = `keywords_relation`.`keyword_id`
where `keywords_relation`.`parent_id` = 1 and `keywords_relation`.`parent_type` = 0
2.) Get the ID's of publications that have those keywords
(?, ?, ?)
would be the values retrieved from the previous query. in this case is the ID of a certain research line. As a result of this query I get an array of keyword ids.
select distinct `parent_id` from `keywords_relation` where `keyword_id` in (?, ?, ?) and `parent_type` = 4
3.) Get the publications
Using the result of the last ID, we feed the following query
select * from `publications` where `id` in (?, ?)
where (?, ?)
is the list of publication IDs.
Request
Could someone help me tidy up this? Maybe in can be achieved in a single query using joins? I can not figure it out.
Please note that the relation between the lines and publications must be loose, that's it, via keywords.
P.s. I am using Laravel so every single of this tables represent a model (Keyword / Publication / Line) and a Pivot (KeywordActivity). In case someone wants to point out a laravel specific solution using eloquent.
Thanks!!!