Reputation: 780
I have a many-to-many relation (MySQL) between labels and companies in an own relation table called RELcomplabel
. It basically looks like this:
CREATE TABLE `RELcomplabel` (
`IDcomplabel` INT NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`IDcomplabel`),
`Fcomp` INT NOT NULL ,
`Flabel` INT NOT NULL
);
Now I want to select all companies (all I want is Fcomp
) having at least a given set of labels, e.g. Flabel = 1 AND Flabel = 2 AND Flabel = 3
. If such a company is in the database, there are three rows in the table RELcomplabel
, all having the same Fcomp
but different Flabel
(1, 2 and 3). The query should also - as good as possible - be dynamic in the number of labels, it should work for two but also for maybe ten given labels.
I found an ugly solution for two or three given labels, posted below. The problems with this solution are:
Ftype
of t0
is different with t1
, t0
different with t2
and t1
different with t2
.(1,2,3)
, just to select one of it.Solution for two labels:
SELECT s.fcomp FROM
(
SELECT
t0.fcomp,
t0.ftype AS type0,
t1.ftype AS type1
FROM
RELcomplabel AS t0
INNER JOIN
RELcomplabel AS t1
ON t0.fcomp = t1.fcomp
WHERE
t0.ftype <> t1.ftype
) AS s
WHERE
s.type0 = 2
AND s.type1 = 3;
Solution for three labels:
SELECT s.fcomp FROM
(
SELECT
t0.fcomp,
t0.ftype AS type0,
t1.ftype AS type1,
t2.ftype AS type2
FROM
RELcomplabel AS t0
INNER JOIN
RELcomplabel AS t1
ON t0.fcomp = t1.fcomp
INNER JOIN
RELcomplabel AS t2
ON t0.fcomp = t2.fcomp
WHERE
t0.ftype <> t1.ftype
AND t0.ftype <> t2.ftype
AND t1.ftype <> t2.ftype
) AS s
WHERE
s.type0 = 1
AND s.type1 = 2
AND s.type2 = 3;
For example, using this testdata:
INSERT INTO `relcomplabel` (`IDcomplabel`,`Fcomp`,`Flabel`) VALUES (1,1,1);
INSERT INTO `relcomplabel` (`IDcomplabel`,`Fcomp`,`Flabel`) VALUES (2,1,2);
INSERT INTO `relcomplabel` (`IDcomplabel`,`Fcomp`,`Flabel`) VALUES (3,1,3);
INSERT INTO `relcomplabel` (`IDcomplabel`,`Fcomp`,`Flabel`) VALUES (4,2,2);
INSERT INTO `relcomplabel` (`IDcomplabel`,`Fcomp`,`Flabel`) VALUES (5,2,3);
I'm searching for a query that gives a result like
Searching for all companies with labels 1 & 2:
-------
|Fcomp|
-------
| 1 |
| 2 |
-------
Searching for all companies with labels 1, 2 & 3:
-------
|Fcomp|
-------
| 1 |
-------
Thanks for reading this, and thanks for your help posting your approach to this problem!
Upvotes: 0
Views: 1096
Reputation: 4287
A sqlfiddle to answer your question http://sqlfiddle.com/#!2/2711e/4
EDIT: Added SQL in case the fiddle disappears:
SELECT Fcomp
FROM RELcomplabel
WHERE Flabel IN (1, 2, 3)
GROUP BY Fcomp
HAVING COUNT(Flabel) >= 3
Upvotes: 3