我有个人信息的下表:
id* sender* recipient* del_by_rec del_by_send
-+----------+-------------+-----------+-----------+
2 tom beth 0 1
5 tom josh 0 1
5 tom chris 1 1
7 ashley burt 1 0
8 jenna tom 1 0
8 jenna ashley 0 0
8 jenna jenna 1 0
10 ashley burt 0 0
,其中
id
是消息ID,sender
和recipient
是用户登录,sender
对邮件id
recipient
id
如果收件人已从收件箱中删除了,则del_by_rec
为1
如果发件人从发件箱中删除了邮件,则del_by_send
为1。id
- sender
- recipient
是主键,id
引用包含该消息的另一个表中的主键id
。一旦当前用户决定这样做,我需要确定是否可以从表中删除:
来自收件人收件箱的:
del_by_send
= 1);和del_by_rec
= 0,则此del_by_rec
= 1,而所有其他收件人都为del_by_rec
= 1。)或来自发件人的发件箱:
del_by_rec
= 1)。否则,当前用户只会通过将相应的del_by_send
或ashley
标记设置为1来标记此消息以进行删除。
有没有办法有效地查询
的此条件返回boolean / int会很棒。
为了爱我,我无法通过此查询(假设用户为8
且她想从收件箱中删除邮件SELECT (
(SUM(del_by_send) > 0) # sender has deleted (at least 1)
&& ((SUM(del_by_rec) + 1) >= COUNT(id)) # only 1 recipient has not deleted yet
&& ((SELECT del_by_rec FROM msg_meta WHERE recipient = 'ashley' AND id = 8) = 0) # and that recipient is this user
)
FROM msg_meta
WHERE id = 8
GROUP BY id
):
id
foreach
无法避免昂贵的WHERE id IN (7,10)
。我为收件人burt
尝试了{{1}},但我无法将其用于子查询.. 帮助。谢谢你们..
答案 0 :(得分:1)
想法1:
反转布尔值(将列称为保留或保存),首先更新用户的删除然后执行:
SELECT id , SUM(del_by_send) + SUM(del_by_rec)
FROM msg_meta
WHERE id = 8
GROUP BY id
第二列中0为0的所有记录都是可删除的。
创意2:
您可以通过两个步骤和一个子查询完成它(可用于1个id,但它可能很慢)
步骤1:更新1或多个消息ID的删除标记(通过rec或发送)
第2步:
SELECT id
FROM msg_meta t
WHERE t.id = 8
AND NOT EXISTS(
SELECT id
FROM msg_meta t2
WHERE t.id = t2.id
AND (t2.del_by_rec = 0 OR t2.del_by_sent = 0)
)
也许其中一个可能会给你你需要的想法或想法3的火花;)
答案 1 :(得分:1)
我的建议是使用子查询在消息级别获取所需的信息,然后将逻辑应用于此。以下查询结束:
select id, (case when sum_del_by_send > 0 and (num_rec - sum_del_by_rec) <= 1
then 'Y'
else 'N'
end) as IsSafeToDelete
from (select id,
sum(del_by_send) as sum_del_by_send,
sum(del_by_rec) as sum_del_by_rec,
count(*) as num_rec
from msg_meta
group by id
) m
这不会考虑当前的收件人。这个变体确实:
select id, (case when sum_del_by_send > 0 and (num_others - sum_del_by_others) = 1
then 'Y'
else 'N'
end) as IsSafeToDelete
from (select id,
sum(del_by_send) as sum_del_by_send,
sum(case when recipient <> @RECIPIENT then del_by_rec end) as sum_del_by_others,
sum(case when recipient <> @RECIPIENT then 1 else 0 end) as num_others,
count(*) as num_rec
from msg_meta
group by id
) m
一次处理所有邮件。要处理特定的消息ID,只需将子查询中的“group by id”替换为:
where id = @ID
(@ RECIPIENT和@ID是您要为其自定义查询的值。)
答案 2 :(得分:0)
这篇文章记录得很好...(我觉得他们都像你的一样。)......
我看到每封邮件只能有一个发件人...那你为什么不把发件人的登录信息和del_by_send标志放在邮件表中呢?
当发件人决定删除邮件时,这将节省相当多的时间只更新一行。通过仅记录每条消息的发件人姓名来节省大量空间......
这应该已经加快了速度,因为你的表会更轻,而且更新永远不会改变多一行。
(这将更接近标准化标准的建议。检查http://en.wikipedia.org/wiki/Database_normalization以获取有关数据库规范化的更多信息)
为了简化您的安全删除任务,我会在消息表中记录与消息有关的人数。 (例如,对于消息ID 5,people_count将为3(Tom,Josh和Chris)。每次用户(发送者或接收者)删除该消息时,递减此计数器。当计数器降至0时,可以安全删除de message。
希望这会好起来......