PostgreSQL使用camelCase列的lead()问题

时间:2016-05-19 00:44:27

标签: sql node.js postgresql node-postgres

所以我正在尝试查询结构如下的时间卡表

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 "clockInTime", "clockOutTime", lead("clockInTime",1)
from "timeCard"
where "clockInTime" between 1462797450 and 1462883850
and "employeeId" = 555

但是我收到了这个错误:

  

错误:函数lead(bigint,integer)不存在

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

  

错误:列“clockintime”不存在

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

3 个答案:

答案 0 :(得分:1)

您需要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;

答案 1 :(得分:1)

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

error: column "clockintime" does not exist

考虑:

它的长短:如果你能避免使用postgres,请不要使用caMelCase标识符:

至于你描述的任务:

  

选择两个值之间的所有行,但也选择该员工的那组行之后的下一行

窗口函数lead()中缺少OVER子句,如@Gordon所指出的那样。但即使修复了语法错误,lead()(或任何其他窗口函数)似乎也不是正确的方法来获得您的要求。它会在结果中的每一行添加一列,而您希望在该集合中添加

我建议UNION ALLORDER BY / LIMIT 1将“下一行”添加到结果集中:

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"未定义唯一,您可能需要向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
);

答案 2 :(得分:-1)

  

但是当我删除双引号时,我最终得到这个,因为我的列名是camelCase

有一件事与另一件事无关。在检测到lead函数丢失的问题之前检测到驼峰式问题,这就是全部。

您只需更正丢失的lead功能问题。