Mysql 如何在首次录制时加入?
由于我对复杂的mysql查询了解有限,我试图从数据库中检索一些信息 故事是这样的;用户收到邀请来我们公司。基于此邀请,用户可以获得多个通知和多个约会。我有三个相关的表格:Mysql 如何在首次录制时加入?,mysql,sql,join,inner-join,greatest-n-per-group,Mysql,Sql,Join,Inner Join,Greatest N Per Group,由于我对复杂的mysql查询了解有限,我试图从数据库中检索一些信息 故事是这样的;用户收到邀请来我们公司。基于此邀请,用户可以获得多个通知和多个约会。我有三个相关的表格: invites ------- | id | name | created | ----------------------------- | 1 | someth1 | 2018-02-03 | | 2 | someth2 | 2018-02-03 | | 3 | someth3 | 2018-02-03
invites
-------
| id | name | created |
-----------------------------
| 1 | someth1 | 2018-02-03 |
| 2 | someth2 | 2018-02-03 |
| 3 | someth3 | 2018-02-03 |
notifications
-------------
| id | inv_id | message |
--------------------------
| 1 | 101 | hello |
| 2 | 287 | hi |
| 3 | 827 | hey |
appointments
------------
| id | inv_id | start_at |
-----------------------------
| 1 | 101 | 2018-02-03 |
| 2 | 287 | 2018-02-08 |
| 3 | 827 | 2018-02-15 |
我目前有一个查询,其中显示了发送给用户的通知列表,用于2018年2月1日之后完成的所有邀请,以及不晚于“2018-03-10”的预约
SELECT id, inv_id, message
FROM notifications
WHERE inv_id IN (
SELECT id
FROM invites as invite
WHERE created > '2018-02-01'
AND id IN (
SELECT inv_id
FROM appointments
WHERE invite.id = inv_id
AND start_at < '2018-03-10'
)
)
ORDER BY inv_id ASC;
我现在想为这些通知添加第一次约会的开始时间
| id | inv_id | message | start_at |
---------------------------------------
| 1 | 101 | hello | 2018-02-03 |
| 2 | 287 | hi | 2018-02-08 |
| 3 | 827 | hey | 2018-02-15 |
但从这里开始,我有点迷失在我该怎么做
是否有人知道我如何添加第一次约会的开始时间,该时间对应于相应通知的邀请?因此,它应该显示通知inv id邀请的第一次约会的开始时间?尝试以下操作:
SELECT id, N.inv_id, message,A.start_at
FROM notifications N
JOIN(
SELECT inv_id,MIN(start_at) start_at
FROM appointments
WHERE inv_id IN (
SELECT id
FROM invites as invite
WHERE created > '2018-02-01'
AND id IN (
SELECT inv_id
FROM appointments
WHERE invite.id = inv_id
AND start_at < '2018-03-10'
)
)
GROUP BY inv_id
)A ON N.inv_id = A.inv_id
WHERE inv_id IN (
SELECT id
FROM invites as invite
WHERE created > '2018-02-01'
AND id IN (
SELECT inv_id
FROM appointments
WHERE invite.id = inv_id
AND start_at < '2018-03-10'
)
)
ORDER BY inv_id ASC;
您不需要太多子查询来获得所需的结果。只需很好地使用联接操作和一个子查询即可获得第一次约会,因此以下是您需要的查询:
select n.id, n.inv_id, n.message, a.startat as start_at
from invites i
inner join notifications n
on i.id = n.inv_id
inner join (select inv_id, min(start_at) startat
from appointments
where start_at < '2018-03-10'
group by inv_id) a
on n.inv_id = a.inv_id
where i.created > '2018-02-01';
请注意,对于您当前的样本数据,您所需的结果是不可能的,因为在您的查询中,您使用invits.id中的notifications.inv_id,并且没有等价物1、2、3与101、287、827不同
因此,我创建了一个SQLFIDLE来显示正在工作的查询,但ID为101、287、827。这是:
此外,如果您想要通知(即使没有预约),请将通知和子查询之间的连接操作从“内部连接”更改为“左连接”使用“分组依据”对项目进行分组,并在SELECT语句中使用MINstart_at尝试“我的更新答案”。希望这正是你所需要的。这是一个常见问题解答&如果你做了所有应该做的事情,你会学到:总是用谷歌搜索你的问题/问题/目标的许多清晰、简洁和具体的版本/措辞,并阅读许多答案。将发现的相关关键字添加到搜索中。如果你找不到答案,就发帖子,用一种变体搜索你的标题和标签的关键词。可能重复我有点困惑。当一个邀请有多个通知时,你想要什么输出?哇!那真让我大吃一惊。我曾经认为sql有它的局限性,但我现在开始思考唯一的局限性是在我的头脑中。在这个答案上有一些不必要的子查询。这只是一个很好的批评,所以/如果你想改进它。等等,我现在看到结果不正确。所有记录的起始位置都相同,而数据库中的起始位置不同。所以我猜它只选择了一条记录。让我更仔细地阅读你的代码,看看为什么会这样。@kramer65,我为你问题的预期结果给出答案。如果您还需要其他内容,请编辑问题。如果同一邀请有第二次通知,则此操作无效。尝试将4287个“嘿”添加到您的应用程序中的通知中SQLFiddle@Nick我不同意你的观点,因为OP说他需要的是第一次预约,而不是第一次通知,所以,如果你有两次通知,他们应该出现。但我理解你的观点,这确实是OP的一个要求。谢谢你注意到这一点!如果OP说你是对的,我会修复它。干杯
select n.id, n.inv_id, n.message, a.startat as start_at
from invites i
inner join notifications n
on i.id = n.inv_id
inner join (select inv_id, min(start_at) startat
from appointments
where start_at < '2018-03-10'
group by inv_id) a
on n.inv_id = a.inv_id
where i.created > '2018-02-01';