SQL 查询优化并在第一行为空时按其他行排序

SQL query optimization and sort by other row if first is empty

SQL 查询:

SELECT 
    T.*,
    U.nick AS author_nick,
    P.id AS post_id,
    P.name AS post_name,
    P.author AS post_author_id,
    U2.nick AS post_author
FROM 
    zero_topics T
LEFT JOIN 
    zero_posts P
ON 
    T.id = P.topic_id
LEFT JOIN 
    zero_players U
ON 
    T.author = U.uuid
LEFT JOIN 
    zero_players U2
ON 
    P.author = U2.uuid
ORDER BY 
    P.id DESC

问题:

  1. 我需要双左连接以从主题的 UUID 获取用户昵称 post
  2. 并非所有主题都会有 post,如您所见,我从 post id(它将是日期)排序,但它显示在最后一个 post 的第一位主题上,并且在没有回复的底部主题上,当 posts 不存在时我如何定义顺序?

1.You 如果需要在不同的列中显示刻痕,则需要双左连接

2.You 可以在你 order by

中使用 case
ORDER BY 
    CASE 
        WHEN P.id is null THEN T.ID
        ELSE P.ID 
    END ASC

最终查询:-

SELECT 
    T.*,
    U.nick AS author_nick,
    P.id AS post_id,
    P.name AS post_name,
    P.author AS post_author_id,
    U2.nick AS post_author
FROM 
    zero_topics T
LEFT JOIN 
    zero_posts P
ON 
    T.id = P.topic_id
LEFT JOIN 
    zero_players U
ON 
    T.author = U.uuid
LEFT JOIN 
    zero_players U2
ON 
    P.author = U2.uuid
ORDER BY 
CASE 
    WHEN P.id is null THEN T.ID
    ELSE P.ID 
END ASC

您实际上有两个来自主题 table 的连接链。一条链将作者直接与主题联系起来,一条链将作者与关于该主题的每个 post 联系起来,其中一个或两个都可以加入。但是,一旦您在链中开始左连接,它就必须继续沿着链的其余部分继续,否则您将取消左连接。实际上,主题作者在长度为 1 的链中,所以您不必担心那个。

如果每个话题都有一个作者,你不需要离开加入第一批玩家table(T.author = U.uuid),因为那总是link .您将离开 post 链以查看主题,即使它们上面没有写 post。

假设那是您想要看到的,那么 order by 子句很可能会保持原样。您将得到一个 post 的列表,按 ID 排序,主题散布在各处,但最终如何排列。任何没有 post 的主题都将集中在结果集的开头或结尾,具体取决于您的设置和 DBMS。

但是,如果您这样写 order by

order by t.Title, p.id;

然后您将获得按标题排序的所有主题,并在每个主题中按 ID 排序关于该主题的 post 文章。任何没有 posts 的主题都会有一行(假设只有一个主题作者)以正确的标题顺序但只显示主题数据。

所以这完全取决于你想看到什么。