2012-01-30 80 views
1

我有两个表,简化为以下组合填充的表格:由顶n行从其他两个表

users: 
+-----+------+-----------+ 
| id | name | timestamp | 
+-----+------+-----------+ 

vouchers: 
+-----+------+ 
| id | code | 
+-----+------+ 

我也有一个第三表,将含有ID的对:

recipients: 
+-----+------+------+ 
| id | u_id | v_id | 
+-----+------+------+ 

当用户的行超过两周时(查询将计划每天运行一次),我需要定期向收件人表中插入新的ID对。不应检索收件人表中已存在的ID。

我现在无法找到两个初始SELECT查询返回的任意配对ID的一种有效的方法:

1. SELECT id FROM users WHERE date < NOW() - INTERVAL 2 WEEK AND id not in (select u_id from recipients) 

2. SELECT id FROM vouchers WHERE id not in (select v_id from recipients) limit *by number of retrieved user IDs* 

到目前为止,我试图加入的都未能达到预期的效果。我已经使用上述两个查询建立了解决方案,使用PHP for循环将插入前的结果配对,但我很清楚这很糟糕。

由于提前,

+0

目前尚不清楚你添加了哪些对。对于大于2周大的每个用户,是否为系统中的每个*未分配的凭证添加一个收件人对? – 2012-01-30 12:18:16

+0

不,你在谈论笛卡尔产品?每个用户配对与每张优惠券配对?下面的比喻可能会有所帮助:用户排在队列中,前面的那些人可以通过旋转式,并在他们通过时获得单一凭证。 – user1177756 2012-01-30 12:44:17

回答

1

您可以创建一个笛卡尔积,并使用NOT EXISTS

Cartesian Product

INNER JOIN在Recipients已经存在除去组合,(逗号)在语义上是等价在没有 的情况下,连接条件:两者都会在 指定的表格之间生成笛卡尔积(即,第一个表格中的每一行e是 连接到第二个表中的每一行)。

SELECT * 
FROM users u 
     , vouchers v 
WHERE u.timestamp < NOW() -INTERVAL 2 WEEK 
     AND NOT EXISTS (
     SELECT * 
     FROM Recipients r 
     WHERE r.u_id = u.id 
       AND r.v_id = v.id 
     ) 
+0

我不确定这是我需要的。我不需要将_every_用户与_every_凭证配对。我需要将每位用户与单一凭证配对,然后确保每张凭证对单个用户是独占的。 – user1177756 2012-01-30 12:51:25

+0

@ user1177756 - 你如何确定最终用户获得最终优惠券? – 2012-01-30 13:05:24

+1

我不这样做,这不是要求。任何用户都可以与任何优惠券配对...等待!我想我只是忽略了一件简单的事情,事实上乍一看我觉得有点白痴。我应该将每个用户标识(例如53)与其相应的凭证标识(再次为53)配对。这样,每个用户将收到一张优惠券,每张优惠券只会使用一次...对不起,漫长的一天。 – user1177756 2012-01-30 13:18:14