2017-08-16 13 views
1

私は自分のウェブサイトのユーザーとの間に接触の仕組みを持っています(いつも2人の間)です。ユーザA(送信者)の二つの規則に基づいて、ユーザB(受信機)にメッセージを送ることができます。特定の行の後に行を数えるには?

  1. ユーザAがユーザBに最大限の2つのメッセージを送信することができ、彼がために、ユーザBから少なくとも1つのメッセージを受け取る必要があります別のメッセージを送信することができます。

  2. ユーザAは、毎日4つのメッセージを最大限に送信できます。

そして、ここに私のテーブル構造である:

-- contact 
+----+-----------+------------+--------------------------+------------+ 
| id | sender_id | receive_id |   message   | date_time | 
+----+-----------+------------+--------------------------+------------+ 
| 1 | 123  | 456  | Hi, how are you?   | 1492431111 | 
| 2 | 123  | 789  | How are you doing?  | 1492431112 | 
| 3 | 456  | 789  | Why would you say that? | 1492431113 | 
| 4 | 123  | 456  | Why don't you answer? | 1492431114 | 
| 5 | 789  | 456  | Because the sky is high | 1492431115 | 
| 6 | 123  | 789  | Hello?     | 1492431116 | 
+----+-----------+------------+--------------------------+------------+ 

そして、ここでは私の現在のクエリです:

INSERT INTO contact(sender_id, receive_id, message, date_time) 
SELECT ?, ?, ?, unix_timestamp() 
FROM dual 
WHERE NOT EXISTS(
    SELECT count(*) AS num_day, 
    FROM contact 
    WHERE user_id = ? 
     AND date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day)) 
    HAVING num_day > 4 
) 

あなたが見ることができるように、唯一の二番目のルールは、私のクエリで実装されています。クエリに最初のルールを実装するにはどうすればよいですか? 「A」と「B」からのメッセージはまだありませんならば、これはおそらく動作しません

SELECT count(*) 
FROM contact 
WHERE sender_id = 'A' 
    AND receive_id = 'B' 
    AND date_time > (
    SELECT max(date_time) 
    FROM contact 
    WHERE sender_id = 'B' 
     AND receive_id = 'A' 
    ) 

注:

+0

一般に、行*の後に*行について話す場合は、それらをある列でソートする必要があります。したがって、この列の値が上記行のこの列の値よりも大きい(または小さい)関連する行を数えることができます。 –

+0

@ JiriTousekもう1つの列を追加する必要がありますか?私はそれで大丈夫です。答えが – stack

+0

と書いてください。いいえ、私はあなたがおそらく "後"について考えているときに列を並べ替えることを意味しています。したがって、この列の値を比較して、その行が「前」または「後」であるかどうかを調べ、後の行だけをカウントすることができます。 –

答えて

0

クエリは、彼らの最後の返信以来、「B」から「A」からのメッセージの数を調べるには - それを考慮に入れてクエリを変更する必要があります。

+0

最大日付がない場合は、1900年1月の日付を提供するmaxの周りにCOALESCEを追加します。したがって、最大日付がないので、最大値はnullです。 –

+0

これは、^ date_time列に 'order by'句を使用する必要があると思います。 – stack

+0

@CaiusJardありがとう、私は本当にMySQLに精通していない。 '> ALL'も同様にうまくいくのだろうか? –

0

データベースにこのロジックを実装するのは良い考えではありません。メッセージを挿入するだけのクエリを探しているようですが、Bに2回以上接触していない場合は書き込みますフロントエンドのアプリケーションではロジックの方が良いでしょう。この目的を達成するために、あなたは、クエリのカップルとしたほうが良いと思います:

Select count(*) from contact where sender_id = A and date_time > unix_timestamp(curdate()) 

とメッセージを拒否し、それが> = 4

実行JiriTousekのクエリであり、それがある場合は、送信を拒否した場合に送信> = 2

deny sendは、フロントエンドを変更することで、メッセージングが不可能になり、決して送信できないメッセージを入力することを避けることができます。このブロックを挿入時に行うのは遅すぎる

関連する問題