SELECT中的临时序列

时间:2014-03-10 21:26:37

标签: sql postgresql sequences

我需要将两个表作为sql查询的一部分加入,并且设置数据库的login表的任何人都不包含每个登录具有唯一ID的列。我需要将login加入一个表,其中每个登录将与另一个表的一行或多行对齐,我希望能够唯一地标识来自login的每一行,而不必依赖于用户标识和登录时间戳是唯一的。

我想做这样的事情:

SELECT l.*, pp.personpositionid
FROM (SELECT login.*, next_unique_bigint() AS loginid FROM login) l, personposition pp, personpositionstatus pps
WHERE l.personid = pp.personid
AND [...]

我可以使用random(),但我宁愿让临时唯一的“id”是顺序的(甚至只是可预测的)而不是随机的。我已经搜索了我正在尝试做的事情,但还没找到我正在寻找的东西。

有没有办法在SQL中执行此操作,尤其是PostgreSQL?我猜是有,我只是不知道要搜索哪些关键字。

如果您使用不同的方式来保持登录记录的持续时间而不是为每一行提供临时ID,那么

奖励积分。

编辑: 这样做的总体目的是获取给定日期范围的登录计数。每个用户都有一组位置(角色?工作?),他们从一个时间点到另一个时间点,我需要根据用户登录时的位置计算登录数。每个用户都可以在任何给定时间有1个或多个头寸。如果他们的用户帐户被停用,他们只能有0个职位,因此当他们有0个职位时,自然不会记录任何登录。

2 个答案:

答案 0 :(得分:2)

您可以使用ROW_NUMBER();

SELECT login.*, ROW_NUMBER() OVER (ORDER BY personid) rn

...用于确定性排序或......

SELECT login.*, ROW_NUMBER() OVER () rn

...只选择伪随机(但顺序)数字。

A small SQLfiddle to test with

其他替代方案是ctid or oid,但它们是特定于PostgreSQL的,并且都有自己的一些限制(在链接页面上记录)

答案 1 :(得分:2)

为什么不在表中添加serial主键列?

ALTER TABLE login ADD column login_id serial;
ALTER TABLE login ADD CONSTRAINT login_pkey PRIMARY KEY(login_id);

第一个操作将重写表并锁定一段时间。 然后我会跑

VACCUM FULL ANALYZE login;

劣质替代方案:row_number()pointed out by @Joachim。为了获得最佳性能,您可以将OVER子句留空:

row_number() OVER () AS rn

除此之外:对列别名使用AS关键字(虽然它们只是表别名的噪音)。

或者你可以使用ctid作为穷人的代理主键。这甚至可以更快

详细说明:
In-order sequence generation

关于dba.SE的例子:
numbering rows consecutively for a number of tables