[英]MySQL many to many relationship issue
我有三個表:articles,tags和articles_tags。 可以想象,每個文章可以有多個標簽,並且每個標簽可以分配給多個文章。 我有一個所謂的主要文章(用唯一的URL表示),並希望根據它們之間的共享標簽獲取相關文章,例如:如果主要文章和文章2具有一個共同的標簽,則同時顯示兩個文章(理想情況下,它不會在結果中顯示/不包含主要文章)。 在SQL查詢中傳遞主要文章的唯一URL。
預期的結果超出了我的能力范圍,因此我們將不勝感激。
復制的代碼(如果上述站點離線):
數據庫和內容:
CREATE TABLE `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`status` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `articles_tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`article_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `articles` (`url`, `title`, `status`) VALUES
('test-article-1', 'Test Article #1', 1),
('test-article-2', 'Test Article #2', 1),
('test-article-3', 'Test Article #3', 0),
('test-article-4', 'Test Article #4', 0),
('test-article-5', 'Test Article #5', 1);
INSERT INTO `tags` (`tag`, `url`) VALUES
('Test', 'test'),
('City', 'city'),
('Nature', 'nature');
INSERT INTO `articles_tags` (`article_id`, `tag_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(2, 2),
(3, 1),
(3, 2),
(4, 2),
(5, 1);
最新(無法正常工作)的SQL查詢:
SELECT
tags.tag,
articles.url,
articles.title
FROM articles
LEFT JOIN articles_tags ON articles_tags.article_id=articles.id
LEFT JOIN tags ON articles_tags.tag_id=tags.id
WHERE (articles.url='test-article-1'
OR tags.id IN (articles_tags.tag_id))
AND articles.status=1
GROUP BY articles.id
結果:如您在SQLFiddle上看到的,它顯示了文章1、2和5,但在我看來,它應該僅顯示1和5。
預期結果:第1條和第5條,理想情況下只有5條(不包括第1條,因為它是主要的)。
我不太確定我是否理解為什么您不希望第2條出現在您的結果中,因為它和第1條都帶有標記2。下面應該仍然返回第2條,因此它可能不是您想要的,但是我能想到的最直接的“類似標記的排名”查詢:
SELECT b.*, COUNT(1) AS tagMatches
FROM articles AS a
INNER JOIN articles_tags AS aTags ON a.id=aTags.article_id
INNER JOIN articles_tags AS bTags
ON aTags.article_id<>bTags.article_id
AND aTags.tag_id = bTags.tag_id
INNER JOIN articles AS b ON bTags.article_id
WHERE a.url = ?
GROUP BY b.url
ORDER BY tagMatches DESC, b.title
;
編輯:這假設文章不能多次使用相同的標簽。 如果不是這種情況,它將使排名傾斜(但是如果重復的標簽應具有更大的權重,則可能會比較有利)。
Edit2:值得注意的是, *
可能不應用於最終結果; 我在這里只是為了簡單起見。
您的OR
條件OR tags.id IN (articles_tags.tag_id))
在以下行上觸發:
INSERT INTO `articles_tags` (`article_id`, `tag_id`) VALUES
(1, 1),
...
(3, 1),
...,
(5, 1);
所以,對我來說結果看起來不錯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.