7
+----------+--------------+-------------------------+
| ticketid | ticketpostid |           date          |
+----------+--------------+-------------------------+
|  1387935 |      3147808 | 2012-09-17 13:33:01     |
|  1387935 |      3147812 | 2012-09-17 13:33:41     |
|  1387938 |      3147818 | 2012-09-17 13:35:01     |
|  1387938 |      3148068 | 2012-09-17 13:37:01     |
|  1387938 |      3148323 | 2012-09-17 14:47:01     |
|  1387939 |      3147820 | 2012-09-17 13:36:01     |
|  1387939 |      3147834 | 2012-09-17 13:36:25     |
|  1387939 |      3147851 | 2012-09-17 13:41:01     |
|  1387939 |      3147968 | 2012-09-17 13:59:06     |
|  1387939 |      3147996 | 2012-09-17 14:03:01     |

これは私が書いたクエリの結果です。同じ ticketid を持つ行が 2 つ以上あります。各チケットIDの最初の2つの日付の時差を見つける必要があります

元。

+----------+--------------+-------------------------+
| ticketid | ticketpostid |           date          |
+----------+--------------+-------------------------+
|  1387935 |      3147808 | 2012-09-17 13:33:01     |
|  1387935 |      3147812 | 2012-09-17 13:33:41     |
|  1387938 |      3147818 | 2012-09-17 13:35:01     |
|  1387938 |      3148068 | 2012-09-17 13:37:01     |
|  1387939 |      3147820 | 2012-09-17 13:36:01     |
|  1387939 |      3147834 | 2012-09-17 13:36:25     |

結果として;

+----------+--------------+
| ticketid |time diff(sec)|
+----------+--------------+
|  1387935 |      40      |
|  1387938 |      120     |
|  1387939 |      24      |

どうすればこれができるか教えてもらえますか?

ありがとう。

4

3 に答える 3

14

lagPostgreSQLの場合、ウィンドウ関数で行を比較する必要があると思います。自己結合してフィルターをかけるよりもはるかに効率的です。これは、MySQLではまだ標準のSQL:2003ウィンドウ関数をサポートしていないように見えるため、機能しません。下記参照。

最も低い2つだけを見つけるには、dense_rankウィンドウ関数を使用してticketid、結果をフィルタリングし、次の行のみを返します。dense_rank() = 2つまり、タイムスタンプが最も低い行から2番目の行を返します。ここで、タイムスタンプlag()が最も低い行が生成されます。

サンプルのDDLと出力を示すこのSQLFiddleを参照してください。

SELECT ticketid, extract(epoch from tdiff) FROM (
  SELECT
      ticketid,
      ticketdate - lag(ticketdate) OVER (PARTITION BY ticketid ORDER BY ticketdate) AS tdiff,
      dense_rank() OVER (PARTITION BY ticketid ORDER BY ticketdate) AS rank
  FROM Table1
  ORDER BY ticketid) x
WHERE rank = 2;

ticketdate日付列の名前として使用しました。これdateは、列のひどい名前(データ型名)であり、決して使用しないでください。多くの状況で機能するには、二重引用符で囲む必要があります。

ポータブルなアプローチは、おそらく他の人が投稿した自己参加です。上記のウィンドウ関数のアプローチは、おそらくOracleでも機能しますが、MySQLでは機能しないようです。私が知る限り、SQL:2003ウィンドウ関数をサポートしていません。

の代わりにSET sql_mode = 'ANSI'を使用すると、スキーマ定義はMySQLで機能します。ウィンドウ関数は機能しないようです。MySQLは句を窒息させます。このSQLFiddleを参照してください。timestamptimestamp with time zoneOVER

于 2012-09-17T12:14:07.847 に答える
2

このクエリを試してください -

INSERT INTO ticket_post(ticketid, ticketpostid, date) VALUES
(1387935, 3147808, '2012-09-17 13:33:01'),
(1387935, 3147812, '2012-09-17 13:33:41'),
(1387938, 3147818, '2012-09-17 13:35:01'),
(1387938, 3148068, '2012-09-17 13:37:01'),
(1387938, 3148323, '2012-09-17 14:47:01'),
(1387939, 3147820, '2012-09-17 13:36:01'),
(1387939, 3147834, '2012-09-17 13:36:25'),
(1387939, 3147851, '2012-09-17 13:41:01'),
(1387939, 3147968, '2012-09-17 13:59:06'),
(1387939, 3147996, '2012-09-17 14:03:01');

SELECT
  ticketid,
  TIME_TO_SEC(TIMEDIFF((
    SELECT t.date FROM ticket_post t WHERE t.ticketid = t1.ticketid AND t.date > t1.date ORDER BY t.date LIMIT 1),
    MIN(date)
  )) diff FROM ticket_post t1
GROUP BY ticketid;

+----------+------+
| ticketid | diff |
+----------+------+
|  1387935 |   40 |
|  1387938 |  120 |
|  1387939 |   24 |
+----------+------+
于 2012-09-17T12:45:26.200 に答える
1
select 
  ticketid
  ,time_to_sec(timediff(t2.date, t1.date))  as timediff
from table t1
join table t2 on t1.ticketid=t2.ticketid and t1.ticketpostid<t2.ticketpostid
于 2012-09-17T12:12:52.323 に答える