5

これが私のテーブル構造です:

users:

id | email

emails:

id | subject | body

user_emails:

user_id | email_id

とてもシンプルなデザインです。ただし、user_emails に関連付けられていないすべての users.id に対して、最初の (最も低い) email.id を選択する必要があります。

説明する:

users:

id | email
1 | email@domain.com
2 | test@lol.com
3 | user@test.com

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 で行うので、mySQL だけでは処理できない場合は、ロジックを PHP で記述する必要があります。

前もって感謝します

編集:おそらく、何千ものユーザー ID と何百もの電子メール ID が存在することに言及する必要があります。これらすべての電子メールを送信するスクリプトは、1 日 1 回実行されます。したがって、これは可能な限り最適化する必要があります。

4

3 に答える 3

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

または、上記のクエリのようにメールの ID を 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
于 2012-06-21T01:23:52.897 に答える
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 );
    }
}
于 2012-07-31T21:43:32.860 に答える
0

以下のクエリで試してみてください

select t.id, min(t.q_id) from (select u.id, e.id as q_id FROM users u CROSS JOIN email e) as t where (t.id, t.q_id) not in (select * from user_emails ) t.id でグループ化

于 2013-05-16T05:45:02.213 に答える