gpt4 book ai didi

mysql - 复杂(ish)连接问题:

转载 作者:行者123 更新时间:2023-11-29 09:10:48 24 4
gpt4 key购买 nike

我在 mySQL 数据库中有下表(注意:这些是总结的,因此它们与这个问题相关,一些列已被省略)。

author (id, username, password etc.)
thread (id, title, content)
tag (id, name)
reply (id, content)
thread_replies (thread_id, reply_id)
author_replies (author_id, reply_id)
thread_tags (thread_id, tag_id)
author_threads (author_id, thread_id)

现在要获取某个作者的帖子,我通常这样做:

SELECT thread.title, thread.id AS thread_id, thread.content, author.username, author.id AS author_id
FROM thread
JOIN author_threads ON thread.id = author_threads.thread_id
JOIN author ON author_threads.author_id = author.id
WHERE author.id = '12'

这工作正常,但是当我尝试获取与这些线程关联的标签时:

SELECT thread.title, thread.id AS thread_id, thread.content, author.username, author.id AS author_id, GROUP_CONCAT( DISTINCT tag.name
ORDER BY tag.name DESC
SEPARATOR ',' ) AS tags
FROM thread
JOIN thread_tags ON thread.id = thread_tags.thread_id
JOIN tag ON thread_tags.tag_id = tag.id
JOIN author_threads ON thread.id = author_threads.thread_id
JOIN author ON author_threads.author_id = author.id
WHERE author.id = '12'
LIMIT 0 , 30

它仅在一列中显示第一个线程以及与该作者关联的所有标签。

我在这里做错了什么?

另外,如果我想计算作者为每个主题获得的回复数量,该怎么做?

最佳答案

由于您在查询中使用聚合 (GROUP_CONCAT),因此您的查询将被分组。由于您没有 group by 子句,因此您的组是整个结果集(因此可以看到作者使用的每个标签)。由于 MySQL 允许在分组语句中使用非分组列,因此您不会收到错误,但不会获得所需的查询。

为了检索正确的结果,您需要根据 thread.id 对查询进行分组。

select
thread.title,
thread.id as thread_id,
thread.content,
author.username,
author.id as author_id,
group_concat(distinct tag.name order by tag.name desc separator ',') as tags

from thread

join thread_tags ON thread.id = thread_tags.thread_id
join tag ON thread_tags.tag_id = tag.id
join author_threads ON thread.id = author_threads.thread_id
join author ON author_threads.author_id = author.id

where author.id = '12'

group by thread.id

limit 0 , 30

这应该在 MySQL 中工作,尽管它不是符合 ANSI 的 SQL,因为您在 select 子句中使用非分组列而不进行任何聚合。您可以保持原样,也可以编写更兼容的 SQL,并在除 thread.id 之外的所有列上使用诸如 max 之类的内容。这看起来不太漂亮,但它是合规的。

SELECT 
max(thread.title) as title,
thread.id as thread_id,
max(thread.content) as content,
max(author.username) as username,
max(author.id) as author_id,
group_concat(distinct tag.name order by tag.name desc separator ',') as tags

from thread

join thread_tags ON thread.id = thread_tags.thread_id
join tag ON thread_tags.tag_id = tag.id
join author_threads ON thread.id = author_threads.thread_id
join author ON author_threads.author_id = author.id

where author.id = '12'

group by thread.id

LIMIT 0 , 30

回复计数

上述查询(以及您的原始查询)适合检索标签列表。您可以编写一个等效的查询来检索回复计数(假设回复不是嵌套的,在这种情况下,您必须使用 MySQL 提供的任何递归查询功能,我对此不熟悉),但要检索两者在单个查询中需要子查询:

select
thread.title,
thread.id as thread_id,
thread.content,
author.username,
author.id,
(select group_concat(distinct tag.name order by tag.name separator ',')

from thread_tags

join tag on tag.id = thread_tags.tag_id

where thread_tags.thread_id = thread.id) as tags,
(select count(1) from thread_replies where thread_id = thread.id) as reply_count

from thread

join author_threads ON thread.id = author_threads.thread_id
join author ON author_threads.author_id = author.id

where author.id = '12'

LIMIT 0 , 30

我已从此查询中删除了 group by,因为我们的聚合已移至子选择中,这意味着外部查询不再分组。

关于mysql - 复杂(ish)连接问题:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5639172/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com