3

いくつかの管轄区域によって作成された交通違反切符を含むPostgreSQLデータベースがあります。

一部の管轄区域では、1つの交通機関の停車地に複数のチケットが書き込まれているかどうかが示されていません。ただし、それは他のフィールドを分析することで推測できます。このデータを検討してください。

ticket_id  timestamp            drivers_license
----------------------------------------------
1          2008-08-07 01:51:00  11111111
2          2008-08-07 01:51:00  11111111
3          2008-08-07 02:02:00  22222222
4          2008-08-07 02:25:00  33333333
5          2008-08-07 04:23:00  44444444
6          2008-08-07 04:23:00  55555555
7          2008-08-07 04:23:00  44444444

私はそれを推測することができます:

  • チケット1と2は、運転免許証番号とタイムスタンプを共有しているため、1つの交通機関で作成されました。
  • 5と7についても同じですが、チケット6がそれらの間にあることに注意してください。おそらく、別の役員が別の場所で同時にチケットを書いていたか、データ入力オペレーターが順不同で何かを入力したのでしょう。

交通停止ごとに一意のIDを持つ別の列を追加したいと思います。値が重複するため、テーブルの主キーにはなりません。例えば:

ticket_id  timestamp            drivers_license  stop_id
--------------------------------------------------------
1          2008-08-07 01:51:00  11111111         1
2          2008-08-07 01:51:00  11111111         1
3          2008-08-07 02:02:00  22222222         2
4          2008-08-07 02:25:00  33333333         3
5          2008-08-07 04:23:00  44444444         4
6          2008-08-07 04:23:00  55555555         5
7          2008-08-07 04:23:00  44444444         4

C#でこれを行うための計算集約型の欲張りアルゴリズムの方法を考えることができますが、機能する効率的なSQLクエリはありますか?

4

4 に答える 4

3

ウィンドウ関数rank()を使用すると、これは驚くほど簡単になります。

SELECT *
      ,rank() OVER (ORDER BY ts, drivers_license)
FROM   tbl
ORDER  BY ticket_id

要求したものを正確に返します。

PostgreSQLではタイプ名であり、すべてのSQL標準では予約語timestampであるためts、列の名前をに変更しました。timestamp

于 2012-03-08T06:55:50.723 に答える
1

おそらく最善の策は、DISTINCTタイムスタンプと運転免許証番号を使用して新しいテーブル(「停止」など)を作成し、行番号を割り当ててから、その新しいテーブルからチケットテーブルを更新することです。

于 2012-03-08T04:10:28.780 に答える
1

効率的なSQLクエリFTW!

私はこれをテストできるコンピューターを使用していないため、構文上の問題が発生している可能性があります。午前中に修正しますが、次のようになります。

WITH uniquez as (SELECT timestamp, drivers_license, 
rank() over (ORDER BY timestamp, drivers_license) as counterz 
FROM ticketTable)

UPDATE ticketTable TT
SET stop_id = uniquez.counterz
WHERE uniquez.timestamp = TT.timestamp
AND uniquez.drivers_license = TT.drivers_license

基本的に、タイムスタンプとdrivers_licenseでグループ化(パーティション)することを選択し、それに対応する行カウンターを用意します。更新を行うときは、この前の選択テーブルの行カウンターを「stop_id」として使用し、タイムスタンプと運転免許証に一致する列を更新します。

于 2012-03-08T04:18:37.187 に答える
-1
SELECT ticket_id,timestamp,drivers_license,substr(drivers_license,1,1) as stop_id
FROM traffic_data;

これがあなたのために働くことを願っています...:)

于 2012-03-08T04:10:13.197 に答える