简体   繁体   English

SQL:如何将两个复杂查询合并为一个,其中第二个需要来自第一个的数据

[英]SQL: How to merge two complex queries into one, where the second one needs data from the first one

The goal is to load a list of chats where the user sending the request is a member in. Some of the chats are group chats (more than two members) and there I want to show the profile pictures from the users who wrote the last three messages.目标是加载一个聊天列表,其中发送请求的用户是其中的成员。一些聊天是群聊(超过两个成员),我想在那里显示写最后三个用户的个人资料图片消息。

The first query to load meta data like the title and the timestamp of the chat is:加载诸如标题和聊天时间戳等元数据的第一个查询是:

SELECT Chat_Users.ID_Chat, Chats.title, Chats.lastMessageAt
FROM Chat_Users
    JOIN Chats ON Chats.ID = Chat_Users.ID_Chat
GROUP BY Chat_Users.ID_Chat
HAVING COUNT(Chat_Users.ID_Chat) = 2 
AND MAX(Chat_Users.ID_User = $userID) > 0
ORDER BY Chats.lastMessageAt DESC
LIMIT 20

The query to load the last three profile pictures from one of the chats loaded with the query above is:从使用上述查询加载的聊天之一加载最后三张个人资料图片的查询是:

SELECT GROUP_CONCAT(innerTable.profilePictures SEPARATOR ', ') AS 'ppUrls',     
        innerTable.ID_Chat 
FROM 
    (
    SELECT Chat_Users.ID_Chat, Users.profilePictureUrl AS profilePictures
    FROM Users
        JOIN Chat_Users ON Chat_Users.ID_User = Users.ID
        JOIN Chat_Messages ON Chat_Messages.ID_Chat = Chat_Users.ID_Chat
    WHERE Chat_Users.ID_Chat = $chatID
    ORDER BY Chat_Messages.timestamp DESC
    LIMIT 3
    ) innerTable
GROUP BY innerTable.ID_Chat

Both are working separately but I want to merge them together so I don't have to run the second query in a loop due to performance reasons.两者都单独工作,但我想将它们合并在一起,因此由于性能原因,我不必在循环中运行第二个查询。 Unfortunately I have no idea how this can be achieved because the second query needs the $chatID, which it only gets from the first query.不幸的是,我不知道如何实现这一点,因为第二个查询需要 $chatID,它只能从第一个查询中获得。

So to clarify the desired result: The list with the profile picture urls (second query) should be just another column in the result of the first query.因此,为了澄清所需的结果:带有个人资料图片网址的列表(第二个查询)应该只是第一个查询结果中的另一列。

I hope it is explained in a reasonably understandable way.我希望以合理可理解的方式对其进行解释。 Any help would be much appreciated.任何帮助将非常感激。

Edit: Sample data from the affected tables:编辑:受影响表中的示例数据:

Table "Chats":表“聊天”: 在此处输入图像描述

Table "Chat_Users":表“Chat_Users”:

在此处输入图像描述

Table "Chat_Messages":表“Chat_Messages”:

在此处输入图像描述

Table "Users":表“用户”:

在此处输入图像描述

This fufils the brief, however it requires a view because MySQL 5.x doesn't support the WITH clause.这满足了简要说明,但是它需要一个视图,因为 MySQL 5.x 不支持WITH子句。

It's long and cluncky and I've tried to shorten it but this is as good as I can get, hopefully someone will pop up in the comments with a way to make it shorter!它又长又笨重,我试图缩短它,但这已经是我能得到的最好的了,希望有人会在评论中弹出一个让它更短的方法!

The view:风景:

CREATE VIEW last_interaction AS
SELECT
    id_chat,
    id_user,
    MAX(timestamp) AS timestamp
FROM chat_messages
GROUP BY id_user, id_chat

The query:查询:

SELECT
    Chat_Users.ID_Chat,
    Chats.title,
    Chats.lastMessageAt,
    urls.pps AS profilePictureUrls
FROM Chat_Users
    JOIN Chats ON Chats.ID = Chat_Users.ID_Chat
    JOIN (
        SELECT
            lo.id_chat,
            GROUP_CONCAT(users.profilePictureUrl) AS pps
        FROM last_interaction lo
        JOIN users ON users.id = lo.id_user
        WHERE (
            SELECT COUNT(*) -- the amount of more recent interactions
            FROM last_interaction li
            WHERE (li.timestamp = lo.timestamp AND li.id_user > lo.id_user)
        ) < 3
        GROUP BY id_chat
    ) urls ON urls.id_chat = Chats.id
GROUP BY Chat_Users.ID_Chat
HAVING COUNT(Chat_Users.ID_Chat) > 2 
AND MAX(Chat_Users.ID_User = $userID)
ORDER BY Chats.lastMessageAt DESC
LIMIT 20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM