我不是数据库专业人员,但目前正在处理一个查询(PHP-> MySQL):
我有3张桌子:
'项目':id,name,link
'ItemsToUsers':id,item_id,user_id
'用户':id,电子邮件
每个“项目”可用性都会提交给我定期更改,我会通过某种算法进行检查。
我的目标是
1)选择所有项目并在飞行时检查它们是否可用
2)如果项目可用,请通过电子邮件通知正在监控它的用户。为此我需要从'ItemsToUsers'中选择用户,然后从Users表中获取他们的电子邮件。
我知道如何以直截了当的方式做到这一点,但我觉得我会遇到很多疑问。 (每个用户的个人选择......)
有没有办法更有效地做到:在一个查询中或通过更改算法? 谢谢你的时间!
答案 0 :(得分:0)
没有足够的信息来确定项目的可用方式。这严重阻碍了查询第2项的能力。
那就是说,我们假设我们添加一个"可用的" Items表的列是一个0的tinyint,不可用,1表示可用。
然后,查询将获得观看可用项目的人的所有电子邮件地址:
SELECT u.email FROM Users AS u JOIN ItemsToUsers AS k ON k.user_id = u.id JOIN Items AS i on i.id = k.item_id WHERE i.available = 1;
或者,您可以使用子查询和IN。
假设您有一个名为Availability的不同表,其中包含列id,item_id和available,这也是一个tinyint,其中包含1表示可用,0表示不可用。
SELECT u.email FROM Users AS u JOIN ItemsToUsers AS k ON k.user_id = u.id WHERE k.item_id IN (SELECT a.item_id FROM Availability AS a WHERE a.available = 1);
同样,如果不了解如何获取可用产品列表,则无法优化查询以检索电子邮件地址列表。
答案 1 :(得分:0)
您的步骤提到在n+1 queries中执行此操作(其中n = Items表中的条目数):
SELECT * FROM Items; -- This is the +1 part
在迭代结果集时,您打算确定它是否可用,如果可用,则通知正在观看它的用户。假设您有一个给定的项目ID,并且您想要选择所有用户的电子邮件,如果该产品ID处于活动状态,那么您可以这样做:
SELECT email FROM Users u
INNER JOIN ItemsToUsers iu ON iu.user_id = u.id
INNER JOIN Items i ON iu.item_id = i.id
WHERE i.id = {your item id}
您将为表中的每个项目运行此查询。这是 n 部分。
一般情况下,您可以为所有正在观看所有有效产品的用户生成电子邮件列表,在之后您已确定哪些应该处于有效状态:
SELECT DISTINCT email FROM Users u
INNER JOIN ItemsToUsers iu ON iu.user_id = u.id
INNER JOIN Items i ON iu.item_id = i.id
WHERE i.is_active = 1
无论您拥有多少用户或项目,这将使总共2个查询完成工作。作为奖励,这个可以为您提供不同的电子邮件,而第一个解决方案仍然需要应用程序级代码来删除多个查询返回的重复项。
答案 2 :(得分:0)
SELECT Items.id, Items.name, Items.link FROM Items
INNER JOIN ItemsToUsers ON ItemsToUsers.item_id = Items.items.id
INNER JOIN Users ON ItemsToUsers.user_id = Users.id ;