2012-06-21 114 views
5

这里是我的表结构:mySQL复杂SELECT查询?

users: 

id | email 

emails: 

id | subject | body 

user_emails: 

user_id | email_id 

这是非常简单的设计。但是,我需要为user_emails中没有关联的所有users.id选择第一个(最低)emails.id。

为了说明:

users: 

id | email 
1 | [email protected] 
2 | [email protected] 
3 | [email protected] 

emails: 

id | subject | body 
1 | sub1 | body1 
2 | sub2 | body2 

user_emails: 

user_id | email_id 
1 | 1 
1 | 2 
2 | 1 

作为数据显示:

  • 用户1接收到的电子邮件1和2已经如此选择应排除 该用户。
  • 用户2只接收到的电子邮件1,所以应该选择用户2 和电子邮件2.
  • 用户3没有收到任何电子邮件,所以应该选择用户3 和电子邮件1.

我将在PHP中这样做,所以任何逻辑都应该用PHP编写,如果不能用mySQL完成的话。

在此先感谢

编辑:我也许应该提到,将有成千上万的用户ID和数百个电子邮件ID的的。发送所有这些电子邮件的脚本将每天运行一次。所以,这应该尽可能优化。

+2

请阅读LEFT JOIN。 –

+0

我有,但我不是很熟悉mySQL,它让我感到困惑。 –

+1

你的答案应该贴出来,然后你应该接受一个答案。 :-) –

回答

0

我想到了一个更简单的解决方案。我在users表中添加了lastSent列。

// Load all emails into an array. Use the id as the key. 
$sql = "SELECT * FROM emails"; 
$query = mysql_query($sql); 
while($row = mysql_fetch_assoc($query)) { 
    $emails[ $row['id'] ] = $row; 
} 

// Load all users into an array. 
$sql = "SELECT id, email, lastSent FROM users"; 
$query = mysql_query($sql); 
while($row = mysql_fetch_assoc($query)) { 
    $users = $row; 
} 

// Loop through each user and send next email from the list based on lastSent value. 
foreach ($users as $user) { 
    $id = $user['lastSent'] + 1; 
    $email = $user['email']; 
    $subject = $emails[$id]['subject']; 
    $body = $emails[$id]['body']; 
    $send = mail($email, $subject, $body); 
    if ($send) { 
      // Update lastSent value. 
     $sql = "UPDATE users SET lastSent='$id' WHERE id='" . $user['id'] . "'"; 
     mysql_query($sql); 
    } 
} 
2

可以尝试如下:

SELECT * from users u 
LEFT JOIN users_emails e ON u.id=e.user_id 
LEFT OUTER JOIN emails m on m.id=1 
WHERE e.user_id is NULL 

或者使用下面如果没有必要的电子邮件标识为1如上查询。

SELECT * from users u 
LEFT JOIN users_emails e ON u.id=e.user_id 
LEFT OUTER join emails m on m.id=(SELECT id from emails order by id limit 1) 
WHERE e.user_id is NULL 
0

给人以从下面的查询

选择t.id,分(t.q_id)一试(SELECT u.id,e.id作为q_id来自用户的U形横JOIN电子邮件E)作为t其中(t.id,t.q_id)不在(select * from user_emails)组中t.id