4

同じメールが 2 分以内に複数回表示されるかどうかを検出するにはどうすればよいですか。

これは私のアウトプットです:

07-02-13 20:08:41   test11@gmail.com
07-02-13 20:09:41   test11@gmail.com
07-02-13 20:21:25   hottie@gmail.com
07-02-13 20:56:51   ugly@gmail.com
07-02-13 21:42:37   selma532@gmail.com
07-02-13 22:09:11   blalbla421@gmail.com

これは私のSQL文です。

$results = $this->EE->db->query("SELECT t.* FROM transactions as t WHERE t.cardid > 0 ORDER BY t.created DESC");

私は彼らに彼女を引き離してもらいたい。そのため、同じメールが 2 分以内に表示された場合は、不正なトランザクションに移行する必要があります。

foreach ($results->result_array() as $filter) 
{

私はこれを手伝うことができます: 私は $filter['created'] を持っています = これには時間が含まれており、私は $filter['email'] を持っています) これには電子メールが含まれています。

if(//Filter goes here) {
  $badtransactions[]=$filter;
} else {
  $cooltransactions[]=$filter;
}

これは私の

<table class="table">
  <h3>Cool Transactions (<?php print_r($sizeCoolTransactions)?>) </h3>
  <thead>
    <tr>
      <th>Time</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    <?php
    //Foreach over cooltransactions
    foreach($cooltransactions as $transaction) {

      // IS NEW?
      $isactive = false;
      if($transaction['created'] > time()-$refresh_timer){
        $isactive = true;
      }

      // Get user mail.
      $member_sql = $this->EE->db->query("SELECT email FROM exp_members WHERE member_id = '".($transaction['cardid']-10000000)."'");

      $member_result = $member_sql->result_array();
      if(isset($member_result[0])) {
        $member_result1 = $member_result[0];
      }
    ?>
    <tr class="<?= $isactive ? 'alert-success' : ''; ?>">

      <td><?= date('d-m-y H:i:s', $transaction['created']); ?></td>
      <td><?= isset($member_result1['email']) ? $member_result1['email'] : '<span style="color:red">Email mangler</span>'; ?></td>
    </tr>
    <?php
      }
    ?>
  </tbody>
</table>
4

2 に答える 2

0

以下のような SQL クエリを作成できます。基本的にこれが行うことは、データベースに返された各行に対して、同じテーブルをチェックして、その電子メール アドレスを持つエントリと、-2 (過去 2 分) より大きい datetime フィールド (この場合は Created) の timediff をチェックし、 +2 (2 分後)。現在のレコードから 2 分以内にレコードが見つかった場合、OccursWithinTimescale フィールドの値が一致したレコードの ID の値に設定されます。したがって、OccursWithinTimescale が null の場合、そのメールはそれ自体から 2 分以内にテーブルで発生していません。

select l1.id, created,
(select max(id) from log where email = l1.email 
    and (
            (minute(timediff(created, l1.created)) <= 2 and minute(timediff(created, l1.created)) >= -2)
        ) 
    and id <> l1.id
    and date(created) = date(l1.created)
) as OccursWithinTimescale, 
l1.email from log l1 

このメソッドの使用には制限があります。たとえば、この種のサブクエリで調べる必要があるインデックス作成については何も含めていません。また、サブクエリは、大規模なデータセットで使用すると、大きな負担になる可能性があります。しかし、それは少なくともオプションですが、おそらく最善ではありません.

OccursWithinTimescale is not null に where 句を追加することで、そのクエリをさらに調整して、2 分以内に発生したすべてのレコードを返すことができます。

于 2013-02-07T22:25:20.050 に答える
0

これはあなたが探しているものですか?残念ながら MSSQL 用に書かれていますが、RDBMS で動作するように構文を変更できることを願っています。

基本的に現在の時刻を設定し (提供されたデータに合わせるためにデフォルトに設定しました)、DATEADD() を使用して範囲を作成します。過去 2 分間のすべての電子メールを提供する範囲内の日時をクエリします。最後に GROUP BY Email HAVING COUNT(*) > 1 でラップして、すべての重複を表示します。

http://sqlfiddle.com/#!3/1d759/17

于 2013-02-07T22:13:20.597 に答える