Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用一个表的对话列表_Mysql_Sql - Fatal编程技术网

Mysql 使用一个表的对话列表

Mysql 使用一个表的对话列表,mysql,sql,Mysql,Sql,我有一张这样的桌子 CREATE TABLE IF NOT EXISTS `users_messages` ( `userMessageId` INT NOT NULL AUTO_INCREMENT, `userMessageFrom` BIGINT(19) NOT NULL, `userMessageTo` BIGINT(19) NOT NULL, `userMessageFromRead` INT(1) NOT NULL DEFAULT 1, `userMessageT

我有一张这样的桌子


CREATE TABLE IF NOT EXISTS `users_messages` (
  `userMessageId` INT NOT NULL AUTO_INCREMENT,
  `userMessageFrom` BIGINT(19) NOT NULL,
  `userMessageTo` BIGINT(19) NOT NULL,
  `userMessageFromRead` INT(1) NOT NULL DEFAULT 1,
  `userMessageToRead` INT(1) NOT NULL DEFAULT 0,
  `userMessageFromDeleted` INT(1) NOT NULL DEFAULT 0,
  `userMessageToDeleted` INT(1) NOT NULL DEFAULT 0,
  `userMessageContent` TEXT(5000) NULL,
  `userCreated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  INDEX `fk_users_messages_users1_idx` (`userMessageFrom` ASC),
  INDEX `fk_users_messages_users2_idx` (`userMessageTo` ASC),
  PRIMARY KEY (`userMessageId`),
  UNIQUE INDEX `userMessageId_UNIQUE` (`userMessageId` ASC),
  CONSTRAINT `fk_users_messages_users1`
    FOREIGN KEY (`userMessageFrom`)
    REFERENCES `typinggame`.`users` (`userUniqueId`)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `fk_users_messages_users2`
    FOREIGN KEY (`userMessageTo`)
    REFERENCES `typinggame`.`users` (`userUniqueId`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;
我正在尝试获取一个对话列表,例如: (摘自我正在查看的另一个stackoverflow帖子)

我尝试过使用UNION,虽然我对它的使用不太熟悉,但无论发生什么情况,我都可以使它只显示用户发送的消息,反之亦然。或者它会显示所有结果,我只需要一个对话列表

有几个线程使用了
CASE
,但我无法复制相同的结果

这是我的密码

SELECT 
                userMessageId,
                u1.userUniqueId AS userMessageFrom,
                u2.userUniqueId AS userMessageTo,
                u1.userName AS userMessageFromName,
                u2.userName AS userMessageToName,
                u1.userEnum AS userMessageFromEnum,
                u2.userEnum AS userMessageToEnum,
                u1.userAvatar AS userMessageFromAvatar,
                u2.userAvatar AS userMessageToAvatar,
                userMessageTo,
                userMessageFrom,
                userMessageToRead,
                userMessageFromRead,
                userMessageToDeleted,
                userMessageFromDeleted,
                userMessageContent,
                userMessageId
            FROM
                users_messages
            INNER JOIN 
                users AS u1 ON u1.userUniqueId = userMessageFrom
            INNER JOIN
                users AS u2 ON u2.userUniqueId = userMessageTo
            WHERE
                userMessageFrom != ? AND userMessageTo = ? AND userMessageToDeleted = 0 OR 
                userMessageFrom = ? AND userMessageTo != ? AND userMessageToDeleted = 0
            ORDER BY
                userMessageId DESC
编辑:联合

SELECT 
    DISTINCT 
    u.userUniqueId AS userUniqueId,
    u.userName AS userName,
    u.userEnum AS userEnum,
    u.userAvatar AS userAvatar,
    userMessageTo,
    userMessageFrom,
    userMessageToRead,
    userMessageFromRead,
    userMessageToDeleted,
    userMessageFromDeleted,
    userMessageContent,
    userMessageId
FROM
    users_messages
JOIN 
    users AS u ON u.userUniqueId = userMessageTo
WHERE
    userMessageFrom = ? AND userMessageToDeleted = 0

UNION
SELECT DISTINCT
    u.userUniqueId AS userUniqueId,
    u.userName AS userName,
    u.userEnum AS userEnum,
    u.userAvatar AS userAvatar,
    userMessageTo,
    userMessageFrom,
    userMessageToRead,
    userMessageFromRead,
    userMessageToDeleted,
    userMessageFromDeleted,
    userMessageContent,
    userMessageId
FROM
    users_messages
JOIN 
    users AS u ON u.userUniqueId = userMessageFrom
WHERE
    userMessageTo = ? AND userMessageToDeleted = 0

从技术上讲,
UNION
不能返回重复数据,因为它是这样工作的,但我认为您的意思是,您已经按列的子集复制了数据。所以,是的,<代码>联合< /代码>对你没有帮助,你需要通过你认为是标识的列聚合“另一个”列。 假设您需要几乎所有Messenger中都能看到的东西,下面是带有注释的脚本。和。 脚本返回每个用户的所有对话,所以要获得单个对话的对话,需要按userId进行筛选

  • 转换为一列中的
    列,以查找用户的最后一条消息
  • 通过每个线程获取最大messageId(它是递增的,因此它将是最后一个),即
    分组依据
    每个
    partyUserId
  • 通过加入消息和用户获取消息和用户信息。对于消息,也可以在第二步中使用
    ROW_NUMBER()
    函数,通过
    partyUserId
    进行分区并按时间戳排序,然后仅选择rownumber=1来实现。将此变体添加为注释部分
  • 根据从上一条消息中获得的信息计算状态列

  • 这个脚本的性能是另一个问题。也许最好实现另一个模型(使用threadId)来获取最后一条消息,而不使用pivot(在某些情况下,不使用聚合)。

    您的代码不包含union,因此很难说您错在哪里。但是您的方法是正确的,因为您需要将列(从、到)转换为行。我删除了联合代码,并将其还原为我现在拥有的代码。因此,您需要从列到列的联合,然后将它们连接到用户infoI。我添加了我尝试使用的联合代码,但它仍然返回重复的代码
    with transpose as (
      /*Inbound messages to user*/
      select
        userMessageTo as userId,
        userMessageFrom as partyUserId,
        userMessageId as msgId,
        userCreated as createdOn
        /*,
          --Can be added for row_number variant
        userMessageContent,
        userMessageToRead
        */
      from users_messages
      /*that is not deleted at his side*/
      where userMessageToDeleted = 0
      
      union
      
      /*Outbound messages from user*/
      select
        userMessageFrom as userId,
        userMessageTo as partyUserId,
        userMessageId as msgId,
        userCreated as createdOn
        /*,
          --Can be added for row_number variant
        userMessageContent,
        userMessageToRead
        */
      from users_messages
      /*that user has not deleted*/
      where userMessageFromDeleted = 0
    )
    , last_msg as (
      select
        userId,
        partyUserId,
        max(msgId) as lastMsgId,
        max(createdOn) as lastMsgDate
      from transpose
    /*  where userId = ?*/
      group by
        userId,
        partyUserId
      order by lastMsgDate desc
      /*To show only top messages*/
      limit 30
    )
    /*Or in this way
    , last_msg_with_info as (
      select *
      from (
        select t.*,
          row_number()
            over(
              partition by userId, partyUserId
              order by createdOn desc
            ) as rn
        from transpose
    --    where userId = ?
      ) as rn_tab
      where rn = 1
    )*/
    
    /*Build conversation list with content of last message in thread*/
    select
      lm.userId,
      lm.partyUserId as conversationWithId,
      lm.lastMsgDate as lastMsgDate,
      m.userMessageContent as lastMsgText,
      case
        when lm.userId = m.userMessageFrom
        then 'Sent'
        else 'Received'
      end as LastMsgDirection,
      /*If user sent message, then no need to check. Else check if he already read it*/
      case
        when lm.userId = m.userMessageFrom
        then 0
        else 1 - m.userMessageToRead
      end as hasUnreadMsgFlag,
      /*If user has sent the message, then check if receiver user has read it*/
      case
        when lm.userId = m.userMessageFrom
        then m.userMessageToRead
        else 0
      end as receiverReadFlag,
      u.userName as conversationWithName,
      u.userEnum as conversationWithEnum,
      u.userAvatar as conversationWithAvatar
    from last_msg as lm
      join users_messages as m
        on lm.lastMsgId = m.userMessageId
      join users as u
        on lm.partyUserId = u.userUniqueId
    order by userId, lastMsgDate