2012-06-21 25 views
5

Hier ist meine Tabellenstruktur:mySQL komplexe SELECT-Abfrage?

users: 

id | email 

emails: 

id | subject | body 

user_emails: 

user_id | email_id 

Es ist sehr einfach aufgebaut. Allerdings muss ich die erste (niedrigste) E-Mail-ID für alle Benutzer-IDs auswählen, die nicht in Benutzer-E-Mails verknüpft sind.

Zur Veranschaulichung:

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 

Wie die Daten zeigen:

  • User 1 empfangene E-Mail 1 und 2 bereits so die Auswahl sollte dass Benutzer ausschließen.
  • User 2 erhalten nur E-Mail-1, so sollte es Benutzer 2 und E-Mail wählen 2.
  • Benutzer 3 hat keine E-Mails nicht erhalten, so sollte es Benutzer 3 und E-Mail 1.

wählen Ich werde das in PHP machen, also sollte jede Logik in PHP geschrieben sein, wenn es nicht mit mySQL alleine gemacht werden kann.

Vielen Dank im Voraus

EDIT: ich wohl erwähnen sollte, dass es Tausende von Benutzer-IDs und Hunderte von E-Mail-IDs sein. Das Skript, das alle diese E-Mails versendet, wird einmal täglich ausgeführt. Also sollte dies so optimiert wie möglich sein.

+2

Lesen Sie auf LINKE VERBINDUNG. –

+0

Ich habe aber ich bin nicht sehr erfahren mit mySQL und es wird für mich verwirrend. –

+1

Ihre Antwort sollte ein solcher gepostet werden, und dann sollten Sie eine Antwort akzeptieren. :-) –

Antwort

0

Ich dachte an eine viel einfachere Lösung für all dies. Ich habe eine lastSent-Spalte zur Benutzertabelle hinzugefügt.

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

Könnte die unten probieren:

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 

Oder die unten verwenden, wenn die ID in E-Mail nicht notwendig 1 wie oben Abfrage zu sein.

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

Probieren Sie mit der unten stehenden Abfrage

wählen t.id, min (t.q_id) aus (SELECT u.id, e.id als q_id FROM users u E-Mails JOIN CROSS e) als t where (t.id, t.q_id) nicht in (select * from user_emails) Gruppe von t.id