过滤子查询的结果

时间:2019-05-18 23:41:34

标签: sql postgresql postgresql-9.6

对于以下查询:

SELECT t_stamp, sum(t_diff) OVER(ORDER BY t_stamp) AS t_sum
FROM (
    SELECT
        t_stamp
        , getdiffabove(t_stamp - lag(t_stamp) OVER(ORDER BY t_stamp),'1s') AS t_diff
    FROM tstmp
) AS td
WHERE t_stamp >= (SELECT t_stamp FROM td WHERE t_diff > '0ms' ORDER BY t_stamp LIMIT 1)

子查询td的结果集包含列t_stampt_diff。我正在尝试过滤td的结果集以删除t_diff上方0ms的第一个值之前的行。我收到错误消息:

ERROR:  relation "td" does not exist

我在查询的这一部分(WHERE子句)不能引用td吗?我该如何解决?

注意:由于Postgres中的CTE限制,我想避免使用CTE。

子查询td的结果集如下:

         t_stamp         |    t_diff
-------------------------+--------------
 2013-08-11 07:12:18.204 | 00:00:00
 2013-08-11 07:12:18.455 | 00:00:00
 2013-08-11 07:12:18.705 | 00:00:00
 2013-08-11 07:13:10.82  | 00:00:51.865
 2013-08-11 07:13:11.07  | 00:00:00

我要过滤此结果集,以便将t_diff的第一个非零值以上的行过滤掉。也就是说,上述结果集中的前三行将被过滤掉。封闭查询将对过滤后的结果集进行操作。

2 个答案:

答案 0 :(得分:1)

该错误由您的td别名命名,仅用于您的from子查询td,不知道td中的别名where

您可以尝试使用cte代替子查询。

with td as (
    SELECT
        t_stamp
        , getdiffabove(t_stamp - lag(t_stamp) OVER(ORDER BY t_stamp),'1s') AS t_diff
    FROM tstmp
)
SELECT t_stamp, sum(t_diff) OVER(ORDER BY t_stamp) AS t_sum
FROM td
WHERE t_stamp >= (
    SELECT t_stamp 
    FROM td 
    WHERE t_diff > '0ms' 
    ORDER BY t_stamp 
    LIMIT 1
)

如果您不想使用cte,则可以尝试使用子查询嵌套子查询

SELECT t_stamp, sum(t_diff) OVER(ORDER BY t_stamp) AS t_sum
FROM (
    SELECT *,SUM(CASE WHEN t_diff > '0ms' THEN 1 ELSE 0 END) OVER(ORDER BY t_stamp) cnt
    FROM (
        SELECT
            t_stamp
            ,getdiffabove(t_stamp - lag(t_stamp) OVER(ORDER BY t_stamp),'1s') AS t_diff
        FROM tstmp
    ) t
) AS td
WHERE cnt > 0

答案 1 :(得分:0)

使用窗口功能:

SELECT t_stamp, sum(t_diff) OVER (ORDER BY t_stamp) AS t_sum
FROM (SELECT td.*,
             MIN(t_stamp) FILTER (WHERE t_diff > '0ms' OVER () as min_t_stamp
      FROM (SELECT t_stamp,
                   getdiffabove(t_stamp - lag(t_stamp) OVER (ORDER BY t_stamp), '1s') AS t_diff,
            FROM tstmp
           ) td
      ) td
WHERE t_stamp >= min_t_stamp;