1

登録時にUnixタイムスタンプを挿入するアプリがあります。私がやりたいのは、先月の記念日からの月の使用量の詳細を計算することです。したがって、最新の記念日が何であるかについてのUNIXタイムスタンプが必要になります。

たとえば、1月5日に登録が送信された場合、顧客の記念日は5日です。したがって、2月15日に使用状況を確認するには、2月5日以降のログからすべてのエントリを取得する必要があります。

登録日を取得するのは簡単です。

SELECT DATE_FORMAT(FROM_UNIXTIME(created), '%d') FROM  accounts

しかし、登録日に基づいて最終記念日のUNIXタイムスタンプを見つけることができません。どうすればいいですか?明確にするために、直近の記念日以降に作成されたすべてのaction_idを返すことを検討しています。

テーブル:

accounts
+------------+------------+
| account_id | created    |
+------------+------------+
| 1          | 1321838910 |
+------------+------------+
....

logs
+------------+------------+------------+
| account_id | action_id  | created    |
+------------+------------+------------+
| 1          | 233        | 1348249244 |
+------------+------------+------------+
| 1          | 263        | 1348257653 |
+------------+------------+------------+
....

注:簡単にするために、たとえば記念日が31日である場合、つまり、誰かがそれらの出来事を考慮したスーパー忍者のステートメントを持っていない限り、何が起こるかを理解するのをやめます。

4

2 に答える 2

2

未検証。あなたの考えを見てください。ロジックは次のとおりです。

  1. 現在の月の最終日を取得します。
  2. アカウントの作成日数を 1 位の結果に追加します。
  3. 現在の日が作成日よりも大きい場合は、2 番目の結果から 1 か月を引きます。それ以外の場合は、2 か月を引きます。

SELECT l.*
FROM accounts a
LEFT JOIN logs l
ON a.account_id = l.account_id 
 AND l.created >= UNIX_TIMESTAMP(
  DATE_SUB(DATE_ADD(LAST_DAY(NOW()), INTERVAL DAY(FROM_UNIXTIME(a.created)) DAY),  
    INTERVAL IF(DAY(NOW()) > DAY(FROM_UNIXTIME(a.created)), 1, 2) MONTH));

編集

これについてもう少し考えてみたところ、記念日の日付に関係なく、以下のクエリが機能する可能性があります。記念日が特定の月にない場合は、その月の最後の日を取る必要があると仮定しました。それは醜いですが、より簡潔にするためにいくつかの変数を入れました。もっと良い方法があるはずです。とにかく、私はテストしていませんが、ロジックは次のとおりです。

  1. 現在の日 > 記念日の場合は、日数を差し引いて日付を取得します。
  2. それ以外の場合、前月の最終日が記念日よりも短い場合は、前月の最終日を使用します。
  3. それ以外の場合は、記念日と前月の最終日の差を前月の最終日から引きます。

SELECT l.*
FROM accounts a
JOIN logs l
ON a.account_id = l.account_id 
 AND l.created >= UNIX_TIMESTAMP(
   IF(@dNow := DAY(NOW()) >= @dCreated := DAY(FROM_UNIXTIME(a.created)),
     DATE_SUB(NOW(), INTERVAL @dNow - @dCreated DAY),
      IF(DAY(@endLastMonth := LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH))) <= @dCreated, 
        @endLastMonth,
        DATE_SUB(@endLastMonth, INTERVAL DAY(@endLastMonth) - @dCreated DAY))));
于 2013-02-05T02:49:31.687 に答える
0

おそらくこれは、最新の作成日を取得するために降順で並べ替えますか?

SELECT DATE_FORMAT(FROM_UNIXTIME(X.created), '%d') 
FROM  (
SELECT CREATED
FROM mytable
WHERE ACCOUNT_ID = ? -- customer id
AND DATE_DIFF(DATE_FORMAT(FROM_UNIXTIME(CREATED),'%Y-%m-%d'), NOW()) MOD 30 = 0 
AND DATE_DIFF(DATE_FORMAT(FROM_UNIXTIME(CREATED),'%Y-%m-%d'), NOW()) / 30 = 1
ORDER BY CREATED DESC LIMIT 1)X;
于 2013-02-05T00:49:42.907 に答える