PostgreSQL lead() 与 camelCase 列有关的问题

PostgreSQL lead() issue with camelCase column

所以我想查询一个时间卡table,它的结构是这样的

employeeId | clockInTime| clockOutTime
-----------+------------+--------------
   555     | 1462797450 | 1462785465 
   555     | 1462883850 | 1462871850 
   111     | 1463056650 | 1463044650 <== skip this
   555     | 1463143050 | 1463131050 <== get this
   555     | 1463229426 | 1463245655 <== but not this

我想要做的是 select 两个值之间的所有行,以及该员工的那组行之后的下一行,而不考虑值

这是我的查询

select "clockInTime", "clockOutTime", lead("clockInTime",1)
from "timeCard"
where "clockInTime" between 1462797450 and 1462883850
and "employeeId" = 555

但是我得到这个错误:

error: function lead(bigint, integer) does not exist

但是当我从 lead() 中删除双引号时,我最终只得到这个,因为我的列名是 camelCase:

error: column "clockintime" does not exist

我正在使用 node.js 和 node-pg 客户端。

您需要 over 子句。我不确定你到底在寻找什么逻辑,但类似于:

select "clockInTime", "clockOutTime",
       lead("clockInTime", 1) over (order by clickInTime)
from "timeCard"
where "clockInTime" between 1462797450 and 1462883850 and "employeeId" = 555;

通常,您希望每个员工都这样:

select "clockInTime", "clockOutTime",
        lead("clockInTime", 1) over (partition by "employeeid" order by clickInTime)
from "timeCard"
where "clockInTime" between 1462797450 and 1462883850 and "employeeId" = 555;

您没有“lead() 中删除双引号”。错误消息显示您实际上从 "clockInTime":

中删除了双引号
error: column "clockintime" does not exist

考虑:

  • Are PostgreSQL column names case-sensitive?

总而言之:如果可以避免,请不要在 Postgres 中使用 caMelCase 标识符:


关于您描述的任务:

select all rows between two values but also the next row after that group of rows for that employee

lead() like 指出的 window 函数中缺少 OVER 子句。但即使修复了语法错误,lead()(或任何其他 window 函数)似乎也不是获得所需内容的正确方法。它向结果中的每一行添加一列,而您想向集合中添加

我建议 UNION ALLORDER BY / LIMIT 1 将 "next" 行添加到结果集中:

SELECT *
FROM   "timeCard"
WHERE  "employeeId" = 555
AND    "clockInTime" BETWEEN 1462797450 AND 1462883850

UNION ALL
(  -- parentheses required
SELECT *
FROM   "timeCard"
WHERE  "employeeId" = 555
AND    "clockInTime" > 1462883850
ORDER  BY "clockInTime"
LIMIT  1
);

("employeeId", "clockInTime") 上的多列 索引 将使这变得非常快,即使对于大表也是如此。

如果 "clockInTime" 未定义 unique,您可能需要向 ORDER BY 添加更多表达式,以便在出现平局时获得确定性结果。

需要括号才能将 LIMITORDER BY 添加到 UNION 查询的单个分支。示例:

如果您还想对前导行进行排序:

(
SELECT *
FROM   "timeCard"
WHERE  "employeeId" = 555
AND    "clockInTime" BETWEEN 1462797450 AND 1462883850
ORDER  BY "clockInTime"
)
UNION ALL
(
SELECT *
FROM   "timeCard"
WHERE  "employeeId" = 555
AND    "clockInTime" > 1462883850
ORDER  BY "clockInTime"
LIMIT  1
);