2

視聴者によるアセットの表示を記録する asset_usages というテーブルがあります。関連するフィールドは次のとおりです。

id (int)
asset_id (int)
viewer_type (string)
viewer_id (int)
viewed_at (datetime)

追加したばかりの新しいフィールド time_between_viewings があり、これは秒を表す int フィールドです。これを、そのアセットが最後に表示されてからの時間 (秒単位) に設定したいと考えています。したがって、次の 4 つのレコードがあるとします。

+-----+----------+-----------+-------------+---------------------+-----------------------+
| id  | asset_id | viewer_id | viewer_type | viewed_at           | time_between_viewings |
+-----+----------+-----------+-------------+---------------------+-----------------------+
| 506 |     7342 |      1182 | User        | 2009-01-05 11:10:01 |      NULL             |
| 509 |     7342 |      1182 | User        | 2009-01-05 11:12:47 |      NULL             |
| 514 |     6185 |      1182 | User        | 2009-01-05 11:14:28 |      NULL             |
| 524 |     6185 |      1182 | User        | 2009-01-05 11:28:18 |      NULL             |
| 618 |     1234 |      1182 | User        | 2009-01-05 11:29:03 |      NULL             |
| 729 |     1234 |      1182 | User        | 2009-01-05 11:29:01 |      NULL             |        
+-----+----------+-----------+-------------+---------------------+-----------------------+

次に、time_between_viewings を次のように設定する必要があります。

+-----+----------+-----------+-------------+---------------------+-----------------------+
| id  | asset_id | viewer_id | viewer_type | viewed_at           | time_between_viewings |
+-----+----------+-----------+-------------+---------------------+-----------------------+
| 506 |     7342 |      1182 | User        | 2009-01-05 11:10:01 |      NULL             |
| 509 |     7342 |      1182 | User        | 2009-01-05 11:12:47 |      166              |
| 514 |     6185 |      1182 | User        | 2009-01-05 11:14:28 |      NULL             |
| 524 |     6185 |      1182 | User        | 2009-01-05 11:28:18 |      830              |
| 618 |     1234 |      1182 | User        | 2009-01-05 11:29:03 |      2                |
| 729 |     1234 |      1182 | User        | 2009-01-05 11:29:01 |      NULL             |     
+-----+----------+-----------+-------------+---------------------+-----------------------+

ここで、166 と 830 は、各ペア間の時間差 (秒単位) です。

このフィールドにデータを入力するための SQL は何でしょうか? 私はそれを理解することはできません。

重要な注意: データは常にデータベースに時系列で挿入されるわけではありません。つまり、2 つのレコード A と B を持つことができます。ここで、B の方が ID が高く、A の方が Viewed_at の値が遅いということです。そのため、ID が小さい最初の一致レコードを探しても、必ずしも同じ人物による以前の表示が得られるとは限りません。データベース内のすべてのレコードを調べる必要があります。

ありがとう!最大

編集 - time_between_viewings は秒を表す int フィールドであると述べました。

編集 - より高いIDを持つが以前のタイムスタンプを持つ行の例として、いくつかの行を追加しました

編集 - 質問を適切に規定していないことに気付きました。time_ between_viewings は、アセットが同じビューアーによって最後に表示されてからの時間、つまり、レコードと、同じ asset_id、viewer_id、および viewer_type を持つ以前の (viewed_at に基づく) レコードとの間の時間と等しくなければなりません。私が提供した例のデータはまだ保持されていますが、いくつかの異なる viewer_id と viewer_type の値を入れて、例を少し肉付けすることもできました。

4

2 に答える 2

0

この SELECT ステートメントは、適切なデータを提供します。ただし、チャンクで更新を行う必要がある場合があります。

UPDATE ステートメントの ORDER BY 句を削除できます。書かれているように、派生データは外側の SELECT ステートメントの行の順序に依存しません。

select asset_id, viewer_id, viewer_type, viewed_at, 
       prev_viewed_at, timestampdiff(second, prev_viewed_at, viewed_at) elapsed_sec
from (select asset_id, viewer_id, viewer_type, viewed_at,
            (select max(t2.viewed_at) 
             from Table1 t2
             where t2.viewed_at < Table1.viewed_at
               and t2.asset_id = Table1.asset_id
               and t2.viewer_id = Table1.viewer_id
            ) prev_viewed_at
      from Table1
      )t3
order by asset_id, viewer_id, viewed_at;
于 2013-07-17T12:05:16.660 に答える
0

サンプルテーブルとデータ挿入を準備していただけると助かります。 ヘルプが必要な場合は
、このリンクを読んで、なぜそれが重要なのかを学んでください: http://tkyte.blogspot.com/2005/06/how-to-ask-questions.html

このリンク: http://sqlfiddle.com/#!2/9719a/2

そして、このクエリを試してください (このクエリは、上記のリンクの下にサンプル データと共にあります)。

select alias1.*,
       timestampdiff( second, previous_viewed_at, viewed_at ) 
         as time_between_viewings
from (
select alias.*,
       (
         select viewed_at from (
             select
             ( select count(*) from asset_usages y
                where x.asset_id = y.asset_id 
                and y.viewed_at < x.viewed_at
              ) as rn,
              x.* 
              from asset_usages x
          ) xyz
          where xyz.asset_id = alias.asset_id 
               and xyz.rn = alias.rn - 1
       ) previous_viewed_at
from (
  select
    ( select count(*) from asset_usages y
      where x.asset_id = y.asset_id 
        and y.viewed_at < x.viewed_at
    ) as rn,
    x.* 
  from asset_usages x
) alias
) alias1;
于 2013-07-16T16:43:12.997 に答える