Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.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
Php 通过UNION group按给定字段连接2个表,并仅获取组中最新的表_Php_Mysql_Sql - Fatal编程技术网

Php 通过UNION group按给定字段连接2个表,并仅获取组中最新的表

Php 通过UNION group按给定字段连接2个表,并仅获取组中最新的表,php,mysql,sql,Php,Mysql,Sql,我正在一个小仪表板中构建一个电子邮件收件箱。是使用其他API的自定义电子邮件客户端。我准备DB结构的方式如下: 输入的表 ╔════╦════════════════════╦═══════════════════╦═════════════════════════════════════════╦══════════════════════╗ ║ id ║ email_from ║ email_to ║ email_body

我正在一个小仪表板中构建一个电子邮件收件箱。是使用其他API的自定义电子邮件客户端。我准备DB结构的方式如下:

输入的

╔════╦════════════════════╦═══════════════════╦═════════════════════════════════════════╦══════════════════════╗
║ id ║     email_from     ║     email_to      ║               email_body                ║         date         ║
╠════╬════════════════════╬═══════════════════╬═════════════════════════════════════════╬══════════════════════╣
║  1 ║ stack@overflow.com ║ mitch@example.com ║ Your question has a downvote for newbie ║ 2017-12-28T00:00:00Z ║
║  2 ║ stack@exchange.com ║ mitch@example.com ║ You gotta learn SQL, buddy :/           ║ 2017-12-28T00:01:43Z ║
║  3 ║ stack@overflow.com ║ mitch@example.com ║ Guess what? 42                          ║ 2017-12-28T00:05:00Z ║
║  3 ║ stack@overflow.com ║ mitch@example.com ║ This is a bot, stop responding          ║ 2017-12-28T00:10:00Z ║
╚════╩════════════════════╩═══════════════════╩═════════════════════════════════════════╩══════════════════════╝
╔════╦═══════════════════╦════════════════════╦════════════════════════════════════╦══════════════════════╗
║ id ║    email_from     ║      email_to      ║             email_body             ║         date         ║
╠════╬═══════════════════╬════════════════════╬════════════════════════════════════╬══════════════════════╣
║  1 ║ mitch@example.com ║ stack@overflow.com ║ That is bad news                   ║ 2017-12-28T00:00:50Z ║
║  2 ║ mitch@example.com ║ stack@exchange.com ║ I know :(                          ║ 2017-12-28T00:01:45Z ║
║  3 ║ mitch@example.com ║ stack@overflow.com ║ Answer to the Ultimate Question... ║ 2017-12-28T00:07:42Z ║
╚════╩═══════════════════╩════════════════════╩════════════════════════════════════╩══════════════════════╝
导出的

╔════╦════════════════════╦═══════════════════╦═════════════════════════════════════════╦══════════════════════╗
║ id ║     email_from     ║     email_to      ║               email_body                ║         date         ║
╠════╬════════════════════╬═══════════════════╬═════════════════════════════════════════╬══════════════════════╣
║  1 ║ stack@overflow.com ║ mitch@example.com ║ Your question has a downvote for newbie ║ 2017-12-28T00:00:00Z ║
║  2 ║ stack@exchange.com ║ mitch@example.com ║ You gotta learn SQL, buddy :/           ║ 2017-12-28T00:01:43Z ║
║  3 ║ stack@overflow.com ║ mitch@example.com ║ Guess what? 42                          ║ 2017-12-28T00:05:00Z ║
║  3 ║ stack@overflow.com ║ mitch@example.com ║ This is a bot, stop responding          ║ 2017-12-28T00:10:00Z ║
╚════╩════════════════════╩═══════════════════╩═════════════════════════════════════════╩══════════════════════╝
╔════╦═══════════════════╦════════════════════╦════════════════════════════════════╦══════════════════════╗
║ id ║    email_from     ║      email_to      ║             email_body             ║         date         ║
╠════╬═══════════════════╬════════════════════╬════════════════════════════════════╬══════════════════════╣
║  1 ║ mitch@example.com ║ stack@overflow.com ║ That is bad news                   ║ 2017-12-28T00:00:50Z ║
║  2 ║ mitch@example.com ║ stack@exchange.com ║ I know :(                          ║ 2017-12-28T00:01:45Z ║
║  3 ║ mitch@example.com ║ stack@overflow.com ║ Answer to the Ultimate Question... ║ 2017-12-28T00:07:42Z ║
╚════╩═══════════════════╩════════════════════╩════════════════════════════════════╩══════════════════════╝
所以,我想做一个类似Gmail的小收件箱,在这里你可以看到所有电子邮件的列表,按电子邮件地址(或对话)分组,按日期排序,在顶部显示最新消息,在每个对话中,只显示该对话的最后一条消息


我的查询尝试

SELECT `email_from` as `thread_email`, `email_body`, `date`
FROM (
SELECT `email_from`, `email_body`, `date` FROM `incoming`
UNION
SELECT `email_to` as `email_from`, `email_body`, `date` FROM `outgoing`
) AS t_union

GROUP BY `email_from`
ORDER BY `date` DESC
结果:

╔════════════════════╦═════════════════════════════════════════╦══════════════════════╗
║    thread_email    ║               email_body                ║         date         ║
╠════════════════════╬═════════════════════════════════════════╬══════════════════════╣
║ stack@exchange.com ║ You gotta learn SQL, buddy :/           ║ 2017-12-28T00:01:43Z ║
║ stack@overflow.com ║ Your question has a downvote for newbie ║ 2017-12-28T00:00:00Z ║
╚════════════════════╩═════════════════════════════════════════╩══════════════════════╝
它仅显示来自
传入
表的结果


我的预期结果

SELECT `email_from` as `thread_email`, `email_body`, `date`
FROM (
SELECT `email_from`, `email_body`, `date` FROM `incoming`
UNION
SELECT `email_to` as `email_from`, `email_body`, `date` FROM `outgoing`
) AS t_union

GROUP BY `email_from`
ORDER BY `date` DESC
  • 按电子邮件地址分组,这表示对话(称为
    thread\u email
    ,基本上每个
    thread\u email
    一行)
  • 每行(或对话,或
    thread\u email
    )仅显示该
    thread\u email
    的最新消息(最后一条消息可能是传入的或传出的)
  • 按日期排序(最近的第一个)
SQL Fiddle:


这是实现这一目标的新手方式吗?对另一种数据库结构有什么建议,这种结构更简单,但也更干净和有序吗?

正如Gordon所说,如果
group by
您的数据减少到一行,但如果您只使用
order by
子句,您仍然会得到重复的数据,它将从union表中获取所有数据

groupby
子句也有一个
having
子句,但它似乎只适用于数字,比如
count(*)>2
和其他内容

在中,我们有一个叫做
数组\u agg
的东西,它将一些数据转换成数组,然后我们可以作为数组访问它

在MySQL中,我发现的唯一相似之处是,使用与“,”连接的字符串中相同的grouped by语句转换所有数据,因此,idk如果这可以解决您的问题,但您可以尝试在应用程序端处理结果,而不是在SQL端处理

您可以这样使用:

select email_from, group_concat(email_body), date from (
  select email_from, email_body, date from incoming union all
  select email_to as email_from, email_body, date from outgoing
) as t_union group by email_from order by date desc;
或者,在最后一种情况下,以非优化的方式:

select email_from, email_body, date from (
  select email_from, email_body, date from incoming union all
  select email_to as email_from, email_body, date from outgoing
) as t_union_1 where date in (
  select max(date) from (
    select email_from, email_body, date from incoming union all
    select email_to as email_from, email_body, date from outgoing
  ) as t_union group by email_from order by date desc
);

为什么要用两个表而不是一个表呢?不完全是,我正在尽可能有条理地构建这个web应用程序。此外,我发现这种基于2表的结构更容易构建特定的对话页面(我的问题是构建对话的主索引)。你对改善我目前的结构有什么建议吗?非常感谢您的帮助:)最后一个案例似乎如预期的那样有效。我希望它能以10000张唱片表现出色。谢谢你,马克西米利安!