我目前有一个从特定用户发送给其他用户的消息列表。此列表包含有关收件人ID的信息,以及邮件发送的时间(以及其他列)。
我需要根据邮件发送的时间对此列表进行排序,同时还要使收件人保持邮件的唯一性。此外,我需要从用户数据库中LEFT JOIN信息,该数据库包含收件人名字和姓氏的列。
为此,我使用以下SQL查询:
SELECT
DISTINCT ON (uc.to_user_id)
uc.id,
uc.to_user_id,
uc.created_at,
u.first_name,
u.last_name
FROM user_communication uc
LEFT JOIN "user" u ON (u.id = uc.to_user_id)
WHERE uc.from_user_id = :user_id
其中user_id是传递给PHP的参数。
但是,此查询不会在发送邮件时对邮件列表进行排序。由于在uc.to_user_id上使用了DISTINCT,因此date_created无法对消息进行排序。
目前,输出如下:
"communications": [
{
"id": "1da9f6ea-8b4d-11e6-8698-2bd5d7c3680b",
"created_at": "2016-10-05 22:43:20",
"user": {
"user_id": "a1cc4284-60cd-11e6-a419-e7a2176c4be3",
"first_name": "Test",
"last_name": "Account"
}
},
{
"id": "05d6c44a-1be7-11e8-be13-abe8f9af8d9c",
"created_at": "2018-02-27 17:52:48",
"user": {
"user_id": "c84d2ff0-f537-11e6-b318-f7c577b9597c",
"first_name": "test",
"last_name": "test"
}
},
{
"id": "16cc5d64-1be7-11e8-87dd-7fa156fb7904",
"created_at": "2018-02-27 17:53:16",
"user": {
"user_id": "c8c6ff00-452f-11e6-91e3-cbb55bd856a3",
"first_name": "test",
"last_name": "account"
}
}
]
此列表目前按字母数字式由user_id(即uc.to_user_id)排序。
我想知道什么是更好的查询来处理这个问题。
答案 0 :(得分:0)
SELECT *
FROM
(
SELECT DISTINCT ON (uc.to_user_id)
uc.id,
uc.to_user_id,
uc.created_at,
u.first_name,
u.last_name
FROM user_communication uc
LEFT JOIN "user" u ON (u.id = uc.to_user_id)
WHERE uc.from_user_id = :user_id)
ORDER BY created_at
答案 1 :(得分:0)
也许您可以为这两个表共享您的模式,但只是将列简化为我们需要看到的内容(即我们只需要一些列,以便我们可以专注于主要问题)。
SELECT
uc.to_user_id,
uc.id,
uc.to_user_id,
uc.created_at,
u.first_name,
u.last_name
FROM user_communication uc
LEFT JOIN "user" u ON (u.id = uc.to_user_id)
WHERE uc.from_user_id = :user_id
GROUP BY uc.to_user_id
ORDER BY uc.to_user_id, uc.created_at
您从上面得到了什么样的结果?我很好奇在这种情况下您想要摆脱DISTINCT
的重复行的样子。
使用GROUP BY
,您可以根据您的要求对某些属性求和或计算。也许这不会帮助您解决问题,因此您可能希望将其删除。
答案 2 :(得分:0)
要仅为每个收件人获取最新邮件,您可以使用以下行的窗口函数:
SELECT * /* Be better to explicitly list your columns again. */
FROM (
SELECT uc.id
, uc.to_user_id
, uc.created_at
, u.first_name
, u.last_name
, ROW_NUMBER() OVER (PARTITION BY uc.to_user_id ORDER BY uc.created_at DESC) as rn
FROM user_communication uc
LEFT JOIN "user" u ON (u.id = uc.to_user_id)
WHERE uc.from_user_id = :user_id
) s1
WHERE s1.rn = 1
我不确定PHP如何使用窗口函数,但这应该可以让您了解如何解决此问题。