3

我有一个 PostgreSQL 数据库,其中包含由几个司法管辖区编写的交通票。

一些司法管辖区没有说明是否在一个交通站写了多张票。但是,这可以通过分析其他领域来推断。考虑以下数据:

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 写在一个交通站,因为它们共享驾驶执照号码和时间戳。
  • 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

准确返回您要求的内容。

我将您的列重命名timestampts,因为timestamp它是 PostgreSQL 中的类型名称和每个 SQL 标准中的保留字

于 2012-03-08T06:55:50.723 回答
1

最好的办法可能是创建一个带有 DISTINCT 时间戳和驾驶执照 #s 的新表(例如“stops”),分配行号,然后从该新表更新票证表。

于 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 回答