我有一个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
我可以推断出:
我想添加另一个列,每个流量站都有唯一的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查询可以工作吗?
答案 0 :(得分:3)
如果您使用window function rank()
,这变得非常简单:
SELECT *
,rank() OVER (ORDER BY ts, drivers_license)
FROM tbl
ORDER BY ticket_id
准确地返回您要求的内容。
我将您的专栏timestamp
重命名为ts
,因为timestamp
是PostgreSQL中的类型名称,并且是每个SQL标准中的reserved word。
答案 1 :(得分:1)
可能你最好的办法是用DISTINCT时间戳和驾驶执照#s创建一个新表(比如“停止”),分配行号,然后从新表中更新票证表。
答案 2 :(得分: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
基本上,您通过timestamp和drivers_license进行组(分区)的选择,并具有与之一致的行计数器。执行更新时,将此前一个选择表的行计数器用作“stop_id”,并更新与时间戳和驱动程序许可证匹配的列。
答案 3 :(得分:-1)
SELECT ticket_id,timestamp,drivers_license,substr(drivers_license,1,1) as stop_id
FROM traffic_data;
希望这对你有用......:)