2012-01-30 49 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