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
问题:
- 我需要双左连接以从主题的 UUID 获取用户昵称 post
- 并非所有主题都会有 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 的主题都会有一行(假设只有一个主题作者)以正确的标题顺序但只显示主题数据。
所以这完全取决于你想看到什么。
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
问题:
- 我需要双左连接以从主题的 UUID 获取用户昵称 post
- 并非所有主题都会有 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 的主题都会有一行(假设只有一个主题作者)以正确的标题顺序但只显示主题数据。
所以这完全取决于你想看到什么。