【问题标题】:Selecting distinct data from two columns in MYSQL从 MYSQL 中的两列中选择不同的数据
【发布时间】:2012-12-18 09:15:54
【问题描述】:

我有一张包含用户之间消息列表的表格。表结构:

Receiver | Sender | Subject   | Message

Daniel   | Admin  | Title 1   | Message 1
Admin    | Daniel | Title 2   | Message 2
Daniel   | Admin  | Title 3   | Message 3
Daniel   | John   | Title 4   | Message 4

假设我以 Daniel 身份登录。我想显示我正在与之通信的人员列表(无论我是发送者还是接收者),以及最新的主题/消息。比如:

Admin | Title 3 | Message 3
John  | Title 4 | Message 4

我已经尝试了一百万种方法来做到这一点,但我就是无法解决!

如果有人可以帮助我区分我是发送者和接收者的最新消息(例如,某种 if 语句),那也会很有帮助。但是,我自己还没有尝试过,所以这不是一个紧迫的问题。

任何帮助将不胜感激:)

【问题讨论】:

  • 我的英文很差,请见谅!我如何比较哪个是最新消息?主要身份证?沟通时间?
  • 主ID(最高数字)。谢谢!

标签: mysql select multiple-columns


【解决方案1】:

为了得到你指定的输出......

SELECT i.correspondent, m.subject, i.msg
FROM (
SELECT sender AS correspondent, MAX(message) msg
FROM mesages
WHERE receiver='Daniel'
GROUP BY sender
UNION
SELECT receiver AS correspondent, MAX(message)
FROM mesages
WHERE sender='Daniel'
GROUP BY receiver )i,
messages m
WHERE i.msg=m.message;

但是还有很多其他方法可以获得通讯员列表。

【讨论】:

  • 这非常接近!不幸的是,它向我显示了来自 Daniel -> Admin 和来自 Admin
  • OK....尝试 SELECT i.correspondent, m.subject, m.msg FROM ( SELECT 通讯员, MAX(msg) as imsg FROM (SELECT sender as通讯员, MAX(message) msg​​ FROM消息 WHERE 接收者='Daniel' GROUP BY 发送者 UNION SELECT 接收者作为通讯者,MAX(消息)来自消息 WHERE 发送者 ='Daniel' GROUP BY 接收者)l GROUP BY 通讯者)i,消息 m WHERE i.imsg=m.message;
【解决方案2】:
SELECT Receiver, Subject, Message 
FROM Messages 
WHERE Sender='Daniel'
UNION
SELECT Sender, Subject, Message
FROM Messages
WHERE Receiver='Daniel';

这将返回“丹尼尔”发送和接收的所有消息。要对此进行扩展并指定哪些记录是发送或接收的消息,您可以将代码修改为以下内容,其中 0 与已发送消息相关,1 与已接收消息相关:

SELECT Receiver, Subject, Message, 0 AS 'MessageType'
FROM Messages 
WHERE Sender='Daniel'
UNION
SELECT Sender, Subject, Message, 1 AS 'MessageType'
FROM Messages
WHERE Receiver='Daniel';

然后,当您返回数据时,您可以根据 0/1 值将其分成两组。

我还建议创建一个表来包含您的用户,以便在您的 Messages 表中您可以通过他们的 ID 而不是仅仅通过他们的名字来引用他们。

【讨论】:

  • 如果我是正确的,这将输出所有消息,而不仅仅是最新消息。
  • 从您最初的帖子中,我没有阅读它,因为您只想要最新消息 - 抱歉。您可以按日期排序(我假设您正在存储每条消息的日期?)然后只从每个查询中选择第一个。
【解决方案3】:

试试这个查询

SELECT Receiver, Subject, Message ,'Sender' as 'type' FROM m WHERE Sender='Danial'
UNION ALL
SELECT Sender, Subject, Message ,'Reciever' as 'type'  FROM m WHERE Receiver='Danial'

编辑:

(SELECT Receiver, Subject, Message ,'Sender' as 'type' FROM m WHERE Sender='Danial' ORDER By message desc limit 1)
UNION ALL
(SELECT Sender, Subject, Message ,'Reciever' as 'type'  FROM m WHERE Receiver='Danial'ORDER By message desc limit 1)

【讨论】:

  • 如果我是正确的,这将输出所有消息,而不仅仅是最新消息。
  • 所以你可以通过最新的 id desc 来订购它们
  • 我只想要与我交流的每个人的最新消息。并非所有消息都按时间顺序排列。那可能吗?谢谢!
【解决方案4】:
SELECT Receiver, Subject, Message FROM m WHERE Sender='<your_name>'
UNION ALL
SELECT Sender, Subject, Message FROM m WHERE Receiver='<your_name>'

这将简单地返回与给定名称有联系的名称列表。您可以操纵此代码以返回它是发送者还是接收者

编辑 (交换cmets后)

这将向您显示每次对话的最后一条消息,无论您要查找的人是发件人还是收件人。该代码基于我的临时表,您必须对其进行一些调整以满足您的需求。

SELECT MAX(id), conv, message FROM (
  SELECT id , CONCAT(sender,'-',receiver) AS 'conversation', message FROM t
  WHERE
    sender = '<person>'
  GROUP BY rec
  UNION
  SELECT id , CONCAT(rec,'-',sender) AS 'conversation', message FROM t
  WHERE
    rec = '<person>'
  GROUP BY sender
) as t
GROUP BY convsersation, message

说明

  1. 在第一个子查询中,我会收到您要查找的人是发件人的每个对话的最新消息。

  2. 第二个子查询为我们提供了该人作为接收者的对话的最新消息的结果。

  3. 使用了 CONCAT,因此我们可以将对话合并在一起

  4. 我们将其包装在主查询中,该查询将仅输出最新消息 MAX(id)。

  5. 如果您需要知道相关人员是接收者还是发送者,您可以在子查询中添加另一列:

    SELECT MAX(id)、对话、消息、类型 FROM ( SELECT id , CONCAT(sender,'-',receiver) AS 'conversation', message, 'sender' AS 'type' FROM t 在哪里 发件人 = '' 按记录分组 联盟 SELECT id , CONCAT(rec,'-',sender) AS 'conversation', message, 'receiver' AS 'type' FROM t 在哪里 记录 = '' 按发件人分组 ) 作为 t 分组对话

(由于某种原因,我无法在第二个查询中创建代码块,请有人编辑它)

【讨论】:

  • 如果我是正确的,这将输出所有消息,而不仅仅是最新消息。
  • 所有的消息,是的。如果您想按时间顺序列出消息,则需要一个日期表或至少 id(unique, auto_increment)
  • 我只想要与我交流的每个人的最新消息。并非所有消息都按时间顺序排列。谢谢!
  • 根据您对 symcbean 的回复 - 如果 Daniel->Admin 已经出现,您不希望 Admin->Daniel 出现吗?
猜你喜欢
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多