2012-06-21 10 views
5

İşte benim masa yapıdır. Ancak, user_emails ile ilişkili olmayan tüm users.id'ler için ilk (en düşük) e-postaları seçmem gerekiyor. mySQL complex SELECT sorgusu?</p> <pre><code>users: id | email emails: id | subject | body user_emails: user_id | email_id </code></pre> <p>Çok basit bir tasarım:

göstermek için: Veri gösterir

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 

gibi:

  • Kullanıcı 1 zaten o kullanıcıyı dışlamak gerekir böylece seçme e 1 ve 2'yi aldı.
  • Kullanıcı 2 sadece e-posta 1 aldı, bu yüzden kullanıcı 2 ve e-posta 2.
  • Kullanıcı 3 tüm e-postaları almadı seçmelidir, bu nedenle kullanıcının seçmelidir 3 ve e-posta 1.

Bunu PHP'de yapacağım, bu yüzden eğer mySQL ile tek başına yapılamazsa, PHP'de herhangi bir mantık yazılmalıdır. peşin

Teşekkür

DÜZENLEME: Muhtemelen kullanıcı kimlikleri binlerce ve e-posta kimliği yılların yüzlerce olacağını belirtmeliyiz. Tüm bu e-postaları gönderecek olan betik günde bir kez yayınlanacak. Yani, bu mümkün olduğunca optimize edilmiş olmalıdır.

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 

Veya gerekli değildir epostalarda kimliği sorgusu yukarıdaki gibi 1 olmak eğer aşağıda kullanın:

+2

SOL JOIN. –

+0

Ben var ama mySQL ile çok deneyimli değilim ve benim için kafa karıştırıcı. –

+1

Cevabınız böyle yayınlanmalı ve sonra bir cevabı kabul etmelisiniz. :-) –

cevap

0

Tüm bunlara çok daha basit bir çözüm düşündüm. Kullanıcı tablosuna bir lastSent sütunu ekledim.

// 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

aşağıda deneyebilir misiniz.

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

aşağıda sorguya

seçme t.id, dak (t.q_id) ile Bir deneyin olarak (u.id SEÇ u e-postaları JOIN kesişmeyecekler kullanıcılar GELEN q_id olarak e.id) t (t.id, t.q_id) 'nin (user_emails kaynağından * seçilmesi) grupta bulunmaması. t.id

İlgili konular