konto usunięte
Temat: [Mysql] Wyszukiwanie po tagach (relacja wiele do wielu)
Witam.Mam takie oto 3 tabelki:
CREATE TABLE `notes` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `tags` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `note_tag_xref` (
`noteId` int(11) NOT NULL,
`tagId` int(11) NOT NULL,
PRIMARY KEY (`noteId`,`tagId`)
);
INSERT INTO `notes` (`id`, `title`, `content`) VALUES
(1, 'hello', 'world'),
(2, 'ala', 'co ma kota'),
(3, 'tomek', 'co ma psa');
INSERT INTO `note_tag_xref` (`noteId`, `tagId`) VALUES
(1, 2),
(2, 1),
(2, 2),
(3, 1),
(3, 3);
INSERT INTO `tags` (`id`, `name`) VALUES
(1, 'aaa'),
(2, 'bbb'),
(3, 'ccc');
Pierwsza zawiera dane (tu akurat notatki), druga tagi, po których chce wyszukiwać notatki, a trzecia jest tabelką łączącą.
Wyszukanie wszystkich notatek z posiadających tag:
SELECT n . *
FROM notes n, tags t, note_tag_xref x
WHERE x.tagId = t.id AND x.noteId = n.id AND t.name = 'aaa'
lub posiadający jeden z wielu tagów:
SELECT n . *
FROM notes n, tags t, note_tag_xref x
WHERE x.tagId = t.id AND x.noteId = n.id AND t.name
IN (
'aaa', 'bbb'
)
nie jest niczym trudnym.
Problemem dla mnie jest skonstruowanie takiego zapytania, abym mógł wyszukiwać notatki posiadające wszystkie przekazane tagi (np. 'aaa' oraz 'bbb').
Fakt, mogę napisać coś takiego:
SELECT n . *
FROM notes n, tags t1, tags t2, note_tag_xref x1, note_tag_xref x2
WHERE (
x1.tagId = t1.id AND x1.noteId = n.id AND t1.name = 'aaa'
) AND (
x2.tagId = t2.id AND x2.noteId = n.id AND t2.name = 'bbb'
)
Ale z każdym kolejnym tagiem, po którym chce szukać, to zapytanie staje się coraz dłuższe i bardziej zagmatwane, a możliwe, że i niewydajne.
Wymyśliłem jeszcze jeden sposób:
SELECT n. * , count( * ) AS __q
FROM notes n, tags t, note_tag_xref x
WHERE t.name
IN (
'aaa', 'bbb'
) AND x.tagId = t.id AND x.noteId = n.id
GROUP BY n.id
HAVING __q =2
ale wydaje mi się on "strasznie na około", a poza tym nie pozwala mi na bardziej skomplikowane zapytania o tagi, typu: pobierz posiadające (aaa oraz bbb) lub ccc .
Może ktoś z was spotkał się z takim problemem. Może rozwiązanie jest banalne, ale nie potrafię na nie wpaść.
Będę wdzięczny za pomoc.