我不是mysql专家,遇到了以下情况。
我有以下3个表,即article,tag和articles_tags,试图以尽可能少的方式描述表的定义。
article: id
tag: id
articles_tags: article_id, tag_id
现在我需要执行以下操作
然后再次从步骤2获取每个文章的所有标签,然后根据它们的出现将它们分组,并以json的形式获得最终结果。
例如名为whatsapp的标签,结果下面将一行显示。
whatsApp,
WhatsAppDisplay,[{“slug”:“messenger”,“displayName”:“Messenger”,“frequency”:159},{“slug”:“apps”,“displayName”:“Apps”,“frequency”:148},{“slug”:“chat”,“displayName”:“Chat”,“frequency”:109},{“slug”:“smartphone”,“displayName”:“Smartphone”,“frequency”:79},{“slug”:“iphone”,“displayName”:“iPhone”,“frequency”:54},{“slug”:“app”,“displayName”:“App”,“frequency”:53},{“slug”:“android”,“displayName”:“Android”,“frequency”:27},{“slug”:“handy”,“displayName”:“Handy”,“frequency”:26},{“slug”:“sprueche”,“displayName”:“Spr\u00fcche”,“frequency”:25},{“slug”:“ios”,“displayName”:“iOS”,“frequency”:25},{“slug”:“facebook”,“displayName”:“Facebook”,“frequency”:24},{“slug”:“nachrichten”,“displayName”:“Nachrichten”,“frequency”:22},{“slug”:“bilder”,“displayName”:“Bilder”,“frequency”:20},{“slug”:“android-smartphone”,“displayName”:“Android-Smartphone”,“frequency”:16},{“slug”:“kontakte”,“displayName”:“Kontakte”,“frequency”:15}]
为此,我编写了以下sql查询。
SELECT t3.slug as testSlug, t3.display_name AS displayName,
(
SELECT CONCAT('[', second_json, ']') AS final_json FROM
(
SELECT GROUP_CONCAT('{', first_json, '}' SEPARATOR ',') AS second_json FROM
(
SELECT
CONCAT
(
'"slug":' , '"', t2.slug , '"', ','
'"displayName":', '"', t2.display_name, '"', ','
'"frequency":' , count(t2.slug)
) AS first_json FROM tipps.tag t2
INNER JOIN tipps.articles_tags ats2 ON ats2.tag_id = t2.id
INNER JOIN tipps.article a2 ON a2.id = ats2.article_id
WHERE a2.id IN (
SELECT a.id FROM tipps.tag t
INNER JOIN tipps.articles_tags ats ON ats.tag_id = t.id
INNER JOIN tipps.article a ON a.id = ats.article_id
WHERE t.slug = 'whatsapp'
)
AND t2.slug != 'whatsapp'
GROUP BY t2.slug
ORDER BY count(t2.slug) DESC
LIMIT 15
) AS third_json
) AS fourth_json
) AS relatedTags
FROM tipps.tag t3
LIMIT 1;
FROM tipps.tag t3 LIMIT 1;
对于那些真正难以理解查询的人。请在下面找到简单版本。
/* step 2 find all tags belongs to each article */
SELECT
t2.slug,
count(t2.slug) AS frequency
FROM tipps.tag t2
INNER JOIN tipps.articles_tags ats2 ON ats2.tag_id = t2.id
INNER JOIN tipps.article a2 ON a2.id = ats2.article_id
WHERE a2.id IN (
/* step one find all articles belongs to a tag */
SELECT a.id
FROM tipps.tag t
INNER JOIN tipps.articles_tags ats ON ats.tag_id = t.id
INNER JOIN tipps.article a ON a.id = ats.article_id
WHERE t.slug = 'whatsapp'
)
/* group them based on their occurances and sort based on occurances */
GROUP BY t2.slug
ORDER BY frequency DESC
LIMIT 15;
可以看出,我使用whatsapp作为常量,现在可以传递t3.tipps而不是常量。这样我就可以在一个查询中选择所有结果。还是对此有更好的方法。任何帮助或线索都会很棒。
答案 0 :(得分:0)
我们要获取标记的所有文章以及这些文章的所有标记。这是获取所需所有数据的原始方法:
select article.id as article_id, tag.id as first_tag_id, article_tags2.tag_id as second_tag_id
from tag
join article_tags article_tags1
on tag.id = article_tags1.tag_id
join article
on article_tags1.article_id = article.id
join article_tags article_tags2
on article.id = article_tags2.article_id
现在我们有了所有标签,每个标签的所有文章以及每个文章的所有标签,我们可以将结果分组:
select article.id as article_id, tag.id as first_tag_id, article_tags2.tag_id as second_tag_id
from tag
join article_tags article_tags1
on tag.id = article_tags1.tag_id
join article
on article_tags1.article_id = article.id
join article_tags article_tags2
on article.id = article_tags2.article_id
group by tag.id, article.id
从这里开始,您可以对适当的组进行group_concat
和其他计算。