I'm trying to find all employees with multiple skills. Here are the tables:
CREATE TABLE IF NOT EXISTS `Employee` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
INSERT INTO `Employee` (`ID`, `Name`, `Region_ID`) VALUES (1, 'Fred Flintstone'), (2, 'Barney Rubble');
CREATE TABLE IF NOT EXISTS `Skill` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
INSERT INTO `Skill` (`ID`, `Name`) VALUES (1, 'PHP'), (2, 'JQuery');
CREATE TABLE IF NOT EXISTS `Emp_Skills` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Emp_ID` bigint(20) unsigned NOT NULL DEFAULT '0',
`Skill_ID` bigint(20) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
INSERT INTO `Emp_Skills` (`ID`, `Emp_ID`, `Skill_ID`) VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1);
Here is the query I have so far:
SELECT DISTINCT(em.ID), em.Name
FROM Employee em
INNER JOIN Emp_Skills es ON es.Emp_ID = em.ID
WHERE es.Skill_ID IN ('1', '2')
This returns both employees, however, I need to find the employee that has both skills (ID 1 and 2).
Any ideas? Thanks
This will do it:
SELECT EmpId, Name
FROM
(
SELECT em.ID as EmpId, em.Name, es.ID as SkillID
FROM Employee em
INNER JOIN Emp_Skills es ON es.Emp_ID = em.ID
WHERE es.Skill_ID IN ('1', '2')
) X
GROUP BY EmpID, Name
HAVING COUNT(DISTINCT SkillID) = 2;
Fiddle here:
The distinct is just in case the same employee has the skill listed twice.
Thanks for the test data.
You can do this with aggregation and a having clause:
SELECT em.ID, em.Name
FROM Employee em INNER JOIN
Emp_Skills es
ON es.Emp_ID = em.ID
GROUP BY em.id, em.name
HAVING sum(es.Skill_id = '1') > 0 and
sum(es.Skill_id = '2') > 0;
Each condition in the having clause counts the number of rows for each employee that have a particular skill. The filter guarantees that both skills are present.
Related
I have 3 MySQL tables: person, review & team.
I have been able to join 2 (person & review) together, however I'd like to include data from the 3rd in my result.
Can someone explain how this is done? :-)
CREATE TABLE `person` (
`id` int NOT NULL AUTO_INCREMENT,
`reference` varchar(100) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `person` (`id`, `reference`, `email`) VALUES
(1, 'PK001', 'paulk#gmail.com');
CREATE TABLE `review` (
`id` int NOT NULL AUTO_INCREMENT,
`review_type` varchar(255) NOT NULL,
`review_body` varchar(255) NOT NULL,
`person_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `review` (`id`, `review_type`, `review_body`, `person_id`) VALUES
(1, 'Personality', 'He has a great personality!', 1),
(2, 'Skills', 'He has multiple skills!', 1);
CREATE TABLE `team` (
`id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
`team_name` varchar(255) NOT NULL,
`value` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
INSERT INTO `team` (`id`, `person_id`, `team_name`, `value`) VALUES
(1, 1, 'Man Utd', 500),
(2, 1, 'Real Madrid', 1500),
(3, 1, 'Ajax', 1000);
Using the following SQL:
SELECT p.id, group_concat(r.review_body)
FROM person p
inner join review r on r.person_id = p.id
group by p.id
gives me the output:
He has a great personality!,He has multiple skills!
However I'd ultimately like my output to be:
He has multiple skills!,He has a great personality,Man Utd-500|Real Madrid-1500|Ajax-1000
Is this possible to do with MySQL ? Any guidance would be greatly appreciated.
I realise I could optimise things a lot better - but I just want to see if I can connect all 3 tables together and go from there.
To get your required concatenated output you need to modify your join query.
For that your new query looks like this:
SELECT p.id,
GROUP_CONCAT(r.review_body) AS reviews,
(SELECT GROUP_CONCAT(CONCAT(team_name, '-', value) SEPARATOR '|')
FROM team
WHERE team.person_id = p.id) AS teams
FROM person p
INNER JOIN review r ON r.person_id = p.id
GROUP BY p.id;
Result :
I have an ERD above. I want to get the price of the room based on channel and also the status (isInvisible) of the hotel that owns the room mentioned.
Also a RESTful-API endpoint for that, I tried many times on this assignment and can't get it right as I use Nodejs to write an API GET /api/${roomId}/price but the query doesn't work:
SELECT RoomPrice.price, Status.isInvisible
FROM RoomPrice
INNER JOIN Status
ON (RoomPrice.RoomID = Room.Id AND RoomPrice.ChannelID = ChannelId)
AND (Status.HotelID = Hotels.ID AND Status.ChannelID = ChannelID)
I use query below to create my database in WorkBench:
DROP TABLE IF EXISTS `address`;
CREATE TABLE `address` (
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`hotel_id` int(9) unsigned NOT NULL,
`address` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY(hotel_id) REFERENCES hotels(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `address` (`hotel_id`, `address`)
VALUES
(1, '7008 Lynch Centers Apt. 596\nLysannemouth, RI 43355'),
(2, '04795 Stanley Mount Apt. 114\nDorrisborough, DC 38070-3542'),
(1, '24586 Eliseo Haven Suite 045\nKossville, WY 17890-7936'),
(2, '639 Toy Corners\nBashirianfort, CA 08964-7258');
DROP TABLE IF EXISTS `channels`;
CREATE TABLE `channels` (
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `channels` (`id`, `url`, `name`)
VALUES
(1, 'http://www.beahan.com/', 'quod'),
(2, 'http://www.douglas.com/', 'sit');
DROP TABLE IF EXISTS `hotels`;
CREATE TABLE `hotels` (
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `hotels` (`id`, `name`)
VALUES
(1, 'illum'),
(2, 'aliquid');
DROP TABLE IF EXISTS `rooms`;
CREATE TABLE `rooms` (
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`hotel_id` int(9) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY(hotel_id) REFERENCES hotels(id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `rooms` (`id`, `hotel_id`, `name`)
VALUES
(1, 1, 'vel'),
(2, 2, 'fugit'),
(3, 1, 'doloribus'),
(4, 2, 'ut'),
(5, 1, 'et');
DROP TABLE IF EXISTS `room_prices`;
CREATE TABLE `room_prices` (
`room_id` int(9) unsigned NOT NULL,
`channel_id` int(9) unsigned NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (room_id, channel_id),
FOREIGN KEY(room_id) REFERENCES rooms(id),
FOREIGN KEY(channel_id) REFERENCES channels(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `room_prices` (`room_id`, `channel_id`, `price`)
VALUES
(1, 1, '50687.86'),
(1, 2, '6687.86'),
(2, 1, '10687.86'),
(2, 2, '274739.20'),
(3, 1, '3828.63'),
(3, 2, '12525.86'),
(4, 1, '2623587.86'),
(4, 2, '125151.00'),
(5, 1, '2358704.85'),
(5, 2, '7347473.86');
DROP TABLE IF EXISTS `status`;
CREATE TABLE `status` (
`hotel_id` int(9) unsigned NOT NULL,
`channel_id` int(9) unsigned NOT NULL,
`isInvisible` BOOLEAN NOT NULL,
PRIMARY KEY (hotel_id, channel_id),
FOREIGN KEY(hotel_id) REFERENCES hotels(id),
FOREIGN KEY(channel_id) REFERENCES channels(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `status` (`hotel_id`, `channel_id`, `isInvisible`)
VALUES
(1, 1, false),
(2, 1, true),
(1, 2, true),
(2, 2, true);
I want that once I query to search for the price of roomId (i.e 1) it returns 2 rows (as the mock data only have 2 rows in channels table) that show:
room_id channel_id price isInvisible
1 1 xxxx.xx 0
1 2 xxxx.xx 1
At this moment, I use the query as DRapp help
SELECT
rp.room_id,
rp.channel_id,
rp.price,
s.isInvisible
FROM
room_prices rp
JOIN status s
ON (rp.channel_id = s.channel_id)
JOIN rooms r
ON (rp.room_id = r.id)
JOIN hotels h
ON (r.hotel_id = h.id)
WHERE rp.room_id = 1
It returns 4 rows (instead of 2 rows as expected)
room_id channel_id price isInvisible
1 1 xxxx.xx 0
1 2 xxxx.xx 1
1 1 xxxx.xx 1
1 2 xxxx.xx 1
You need to identify each of the relations as your ERD shows. Each table is joined to its respective context. Dont jump/skip. The only time you can in this scenario is to skip through the channels since the RoomPrice and Status table EACH have a "ChannelId" to qualify the join
SELECT
rp.price,
s.isInvisible
FROM
Room_Prices rp
JOIN Rooms r
on rp.room_id = r.id
JOIN Status s
ON rp.Channel_ID = s.Channel_Id
AND r.hotel_id = s.hotel_id
WHERE
rp.room_id = 1
I had to revise the query. I looked deeper and noticed your CHANNEL table ALSO had the Hotel, so I had to go from the room prices to the room table. From the room table, I can get the hotel. Now that I have the channel from room prices, AND the hotel ID from the rooms table. So NOW I join to the status table on BOTH columns getting the expected single row per room you are expecting.
I'm trying to find out, if any number in a group_concat result is in a given set of numbers.
This example data can be used to try it out:
CREATE TABLE `events` (
`eventid` int(11) NOT NULL AUTO_INCREMENT,
`eventname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`eventid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `events`
-- ----------------------------
BEGIN;
INSERT INTO `events` VALUES ('1', 'my event');
COMMIT;
-- ----------------------------
-- Table structure for `events2groups`
-- ----------------------------
CREATE TABLE `events2groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`eventid` int(11) DEFAULT NULL,
`groupid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `events2groups`
-- ----------------------------
BEGIN;
INSERT INTO `events2groups` VALUES ('1', '1', '5'), ('2', '1', '3'), ('3', '1', '1');
COMMIT;
-- ----------------------------
-- Table structure for `groups`
-- ----------------------------
CREATE TABLE `groups` (
`groupid` int(11) NOT NULL AUTO_INCREMENT,
`groupname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`groupid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `groups`
-- ----------------------------
BEGIN;
INSERT INTO `groups` VALUES ('1', 'group1'), ('2', 'group2'), ('3', 'group3'), ('4', 'group4'), ('5', 'group5');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
Then fire this query:
SELECT GROUP_CONCAT(groups.groupid),
IF ( GROUP_CONCAT(groups.groupid) IN (1,2,3), 'yes', 'no' ) as isInGroup
FROM `events`
LEFT JOIN events2groups ON events.eventid = events2groups.eventid
LEFT JOIN groups ON events2groups.groupid = groups.groupid
GROUP BY events.eventid
the first result column shows, that the event has the groups 5, 3 and 1.
The user has the groups 1, 2 and 3, so the 3 and the 1 match. How can I query this to get the 'yes' from the IF?
Why use the group_concat() results? Just use conditional aggregation:
SELECT GROUP_CONCAT(groups.groupid),
(case when max(groups.group_id in (1, 2, 3)) > 0 then 'yes' else 'no'
end) as isInGroup
FROM `events` LEFT JOIN
events2groups
ON events.eventid = events2groups.eventid LEFT JOIN
groups
ON events2groups.groupid = groups.groupid
GROUP BY events.eventid;
SELECT GROUP_CONCAT(groups.groupid),
GROUP_CONCAT(case when groups.groupid IN (1,2,3) then 'yes' else 'no' end) as isInGroup
FROM `events`
LEFT JOIN events2groups ON events.eventid = events2groups.eventid
LEFT JOIN groups ON events2groups.groupid = groups.groupid
GROUP BY events.eventid
;
result
no,yes,yes
(please see the database structure I'm testing with at the bottom of this post.)
I execute this query:
SELECT m.title, GROUP_CONCAT(DISTINCT(d.name) SEPARATOR ',') d FROM movies m
INNER JOIN movies_seen s
ON s.object_id = m.id
LEFT JOIN movies_directors_connections dc
ON dc.movie_id = m.id
LEFT JOIN movies_directors d
ON d.id = dc.director_id
With this result:
title | d
Pulp Fiction | Quentin Tarantino,George Butler,Robert Fiore
But I'm trying to get this:
title | d
Pulp Fiction | Quentin Tarantino
Pumping Iron | George Butler,Robert Fiore
And suggestions? :)
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(90) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 ;
CREATE TABLE `movies_seen` (
`object_id` int(10) NOT NULL DEFAULT '0',
`date` varchar(10) NOT NULL DEFAULT '0');
CREATE TABLE `movies_directors` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 ;
CREATE TABLE IF NOT EXISTS `movies_directors_connections` (
`movie_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
`director_id` mediumint(8) unsigned NOT NULL DEFAULT '0'
) ENGINE=MyISAM;
And then some test data:
INSERT INTO `movies` (`id`, `title`) VALUES
(1, 'Pulp Fiction'), (2, 'Pumping Iron');
INSERT INTO `movies_seen` (`object_id`, `date`) VALUES
(1, 1359511222), (2, 1359511223);
INSERT INTO `movies_directors` (`id`, `name`) VALUES
(1, 'Quentin Tarantino'),
(2, 'George Butler'),
(3, 'Robert Fiore');
INSERT INTO `movies_directors_connections` (`movie_id`, `director_id`) VALUES
(1, 1), (2, 2), (2, 3);
you just need to add GROUP BY clause
SELECT m.title,
GROUP_CONCAT(DISTINCT(d.name) SEPARATOR ',') d
FROM movies m
INNER JOIN movies_seen s
ON s.object_id = m.id
LEFT JOIN movies_directors_connections dc
ON dc.movie_id = m.id
LEFT JOIN movies_directors d
ON d.id = dc.director_id
GROUP BY m.title
SQLFiddle Demo
OTHER LINK
MySQL GROUP BY clause
First execute these tables and data dumps :-
CREATE TABLE IF NOT EXISTS `Tags` (
`id_tag` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`id_tag`),
UNIQUE KEY `tag` (`tag`),
KEY `id_tag` (`id_tag`),
KEY `tag_2` (`tag`),
KEY `tag_3` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
(1, 'key1'),
(2, 'key2');
CREATE TABLE IF NOT EXISTS `Tutors_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_tutor` int(10) default NULL,
KEY `Tutors_Tag_Relations` (`id_tag`),
KEY `id_tutor` (`id_tutor`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `Tutors_Tag_Relations` (`id_tag`, `id_tutor`) VALUES
(1, 1),
(2, 1);
The following query finds all the tutors from Tutors_Tag_Relations table which have reference to at least one of the terms "key1" or "key2".
SELECT td . *
FROM Tutors_Tag_Relations AS td
INNER JOIN Tags AS t ON t.id_tag = td.id_tag
WHERE t.tag LIKE "%key1%"
OR t.tag LIKE "%key2%"
Group by td.id_tutor
LIMIT 10
Please help me modify this query so that it returns all the tutors from Tutors_Tag_Relations table which have reference to both the terms "key1" and "key2" (AND logic instead of OR logic). Please suggest an optimized query considering huge number of data records (the query should NOT individually fetch two sets of tutors matching each keyword and then find the intersection).
Update
Taking the question to the next level. Please run the following fresh queries :-
===================================================================================
CREATE TABLE IF NOT EXISTS learning_packs_tag_relations (
id_tag int(10) unsigned NOT NULL DEFAULT '0',
id_tutor int(10) DEFAULT NULL,
id_lp int(10) unsigned DEFAULT NULL,
KEY Learning_Packs_Tag_Relations_FKIndex1 (id_tag),
KEY id_lp (id_lp),
KEY id_tag (id_tag)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS learning_packs (
id_lp int(10) unsigned NOT NULL AUTO_INCREMENT,
id_status int(10) unsigned NOT NULL DEFAULT '2',
id_author int(10) unsigned NOT NULL DEFAULT '0',
name varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (id_lp)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;
CREATE TABLE IF NOT EXISTS tutors_tag_relations (
id_tag int(10) unsigned NOT NULL DEFAULT '0',
id_tutor int(10) DEFAULT NULL,
KEY Tutors_Tag_Relations (id_tag),
KEY id_tutor (id_tutor),
KEY id_tag (id_tag)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS users (
id_user int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL DEFAULT '',
surname varchar(155) NOT NULL DEFAULT '',
PRIMARY KEY (id_user)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=52 ;
CREATE TABLE IF NOT EXISTS tutor_details (
id_tutor int(10) NOT NULL AUTO_INCREMENT,
id_user int(10) NOT NULL,
PRIMARY KEY (id_tutor)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=60 ;
CREATE TABLE IF NOT EXISTS tags (
id_tag int(10) unsigned NOT NULL AUTO_INCREMENT,
tag varchar(255) DEFAULT NULL,
PRIMARY KEY (id_tag),
UNIQUE KEY tag (tag)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
ALTER TABLE learning_packs_tag_relations
ADD CONSTRAINT Learning_Packs_Tag_Relations_ibfk_1 FOREIGN KEY (id_tag) REFERENCES tags (id_tag) ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE learning_packs
ADD CONSTRAINT Learning_Packs_ibfk_2 FOREIGN KEY (id_author) REFERENCES users (id_user) ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE tutors_tag_relations
ADD CONSTRAINT Tutors_Tag_Relations_ibfk_1 FOREIGN KEY (id_tag) REFERENCES tags (id_tag) ON DELETE NO ACTION ON UPDATE NO ACTION;
INSERT INTO test.users (
id_user ,
name ,
surname
)
VALUES (
NULL , 'Vivian', 'Richards'
), (
NULL , 'Sachin', 'Tendulkar'
);
INSERT INTO test.users (
id_user ,
name ,
surname
)
VALUES (
NULL , 'Don', 'Bradman'
);
INSERT INTO test.tutor_details (
id_tutor ,
id_user
)
VALUES (
NULL , '52'
), (
NULL , '53'
);
INSERT INTO test.tutor_details (
id_tutor ,
id_user
)
VALUES (
NULL , '54'
);
INSERT INTO test.tags (
id_tag ,
tag
)
VALUES (
1 , 'Vivian'
), (
2 , 'Richards'
);
INSERT INTO test.tags (id_tag, tag) VALUES (3, 'Sachin'), (4, 'Tendulkar');
INSERT INTO test.tags (id_tag, tag) VALUES (5, 'Don'), (6, 'Bradman');
INSERT INTO test.learning_packs (id_lp, id_status, id_author, name) VALUES ('1', '1', '52', 'Cricket 1'), ('2', '2', '52', 'Cricket 2');
INSERT INTO test.tags (id_tag, tag) VALUES ('7', 'Cricket'), ('8', '1');
INSERT INTO test.tags (id_tag, tag) VALUES ('9', '2');
INSERT INTO test.learning_packs_tag_relations (id_tag, id_tutor, id_lp) VALUES ('7', '52', '1'), ('8', '52', '1');
INSERT INTO test.learning_packs_tag_relations (id_tag, id_tutor, id_lp) VALUES ('7', '52', '2'), ('9', '52', '2');
===================================================================================
About the new system -
- The system now has 4 more tables - tutors, Users (linked to tutor_details), learning_packs, learning_packs_tag_relations
- Tutors create packs - tag relations for tutors stored in tutors_tag_relations and those for packs stored in learning_packs_tag_relations.
Now I want to search learning_packs, with the same AND logic. Help me modify the following query so that searching pack name or tutor's name, surname results all active packs (either directly those packs or packs created by those tutors).
==================================================================================
select lp.*
from Learning_Packs AS lp
LEFT JOIN Learning_Packs_Tag_Relations AS lptagrels ON lp.id_lp = lptagrels.id_lp
LEFT JOIN Tutors_Tag_Relations as ttagrels ON lp.id_author = ttagrels.id_tutor
LEFT JOIN Tutor_Details AS td ON ttagrels.id_tutor = td.id_tutor
LEFT JOIN Users as u on td.id_user = u.id_user
JOIN Tags as t on (t.id_tag = lptagrels.id_tag) or (t.id_tag = ttagrels.id_tag)
where lp.id_status = 1 AND ( t.tag LIKE "%Vivian%" OR t.tag LIKE "%Richards%" )
group by lp.id_lp HAVING count(lp.id_lp) > 1 limit 0,20
As you can see, searching "Cricket 1" returns that pack but searching Vivian Richards does not return the same pack.
Please help
Pretty simple if using Group and Having. This should get what you are looking for.
SELECT id_tutor
FROM Tutors_Tag_Relations AS td
INNER JOIN Tags AS t ON t.id_tag = td.id_tag
WHERE t.tag LIKE "%key1%"
or t.tag LIKE "%key2%"
group by id_tutor
having count(id_tutor)>1