在 PostgreSQL 查询的窗口函数中使用别名

发布于 2024-12-12 19:17:42 字数 2648 浏览 3 评论 0 原文

我正在使用 PostgreSQL 版本 9.1 并查看 Postgres 文档,我知道可以执行以下操作:

SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;

这适用于我的查询。

现在我需要能够在 OVER (ORDER BY ...) 中指定别名而不是列名?

我已经尝试过:

编辑:我之前忘记将rank()添加到此查询中:

SELECT salary, <complex expression> as result, rank() OVER (ORDER BY result) FROM empsalary;

并且我收到一条错误消息,指出column“result”确实不存在。

是否可以在此处指定别名而不是列名?我错过了一些特殊的语法吗?

编辑:

我正在使用 Hibernate,并使用一些用于窗口函数的本机 SQL。生成并执行的完整 SQL 如下:

select 
       rank() OVER (ORDER BY deltahdlcOverruns DESC) as rank, 

       this_.deviceNo as y1_, 

       (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
        INNER JOIN enddevicestatistic _dev_ ON _dev_.id = _abs_.id 
        INNER JOIN linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
        INNER JOIN iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
        WHERE this_.deviceNo=_dev_.deviceNo AND _abs_.dateTime <= '3910-06-07 00:00:00.0'
        ORDER BY _abs_.dateTime DESC LIMIT 1
       ) 
       - 
       (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
        INNER JOIN enddevicestatistic _dev_ ON _dev_.id = _abs_.id 
        INNER JOIN linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
        INNER JOIN iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
        WHERE this_.deviceNo=_dev_.deviceNo AND _abs_.dateTime >= '3870-06-01 00:00:00.0' 
        ORDER BY _abs_.dateTime LIMIT 1
       ) 
       AS deltahdlcOverruns from EndDeviceStatistic this_ 

       inner join AbstractPerformanceStatistic this_1_ on this_.id=this_1_.id 
       inner join AbstractEntity this_2_ on this_.id=this_2_.id 
       left outer join RawEndDeviceStatistic this_3_ on this_.id=this_3_.id 
       left outer join LinkStatistic l2_ on this_.linkStatistic_id=l2_.id 
       left outer join AbstractPerformanceStatistic l2_1_ on l2_.id=l2_1_.id 
       left outer join AbstractEntity l2_2_ on l2_.id=l2_2_.id 
       left outer join RawLinkStatistic l2_3_ on l2_.id=l2_3_.id 
       left outer join IPTStatistic i1_ on l2_.iptStat_id=i1_.id 
       left outer join AbstractPerformanceStatistic i1_1_ on i1_.id=i1_1_.id 
       left outer join AbstractEntity i1_2_ on i1_.id=i1_2_.id 
       left outer join RawIPTStatistic i1_3_ on i1_.id=i1_3_.id 

       where this_1_.dateTime between ? and ? 

       group by this_.deviceNo limit ?

I am using PostgreSQL version 9.1 and looking at the Postgres docs, I know it is possible to do the following:

SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;

and this works for my queries.

Now I need to be able to specify an alias instead of a column name in the OVER (ORDER BY ...) ?

I have tried this:

EDIT: I previously forgot to add the rank() to this query:

SELECT salary, <complex expression> as result, rank() OVER (ORDER BY result) FROM empsalary;

and I am getting an error saying that column "result" does not exist.

Is it possible to specify an alias instead of a column name here? Am I missing some special syntax?

EDIT:

I am using Hibernate, with some native SQL for the window function. The full SQL that is generated and executed is below:

select 
       rank() OVER (ORDER BY deltahdlcOverruns DESC) as rank, 

       this_.deviceNo as y1_, 

       (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
        INNER JOIN enddevicestatistic _dev_ ON _dev_.id = _abs_.id 
        INNER JOIN linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
        INNER JOIN iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
        WHERE this_.deviceNo=_dev_.deviceNo AND _abs_.dateTime <= '3910-06-07 00:00:00.0'
        ORDER BY _abs_.dateTime DESC LIMIT 1
       ) 
       - 
       (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
        INNER JOIN enddevicestatistic _dev_ ON _dev_.id = _abs_.id 
        INNER JOIN linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
        INNER JOIN iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
        WHERE this_.deviceNo=_dev_.deviceNo AND _abs_.dateTime >= '3870-06-01 00:00:00.0' 
        ORDER BY _abs_.dateTime LIMIT 1
       ) 
       AS deltahdlcOverruns from EndDeviceStatistic this_ 

       inner join AbstractPerformanceStatistic this_1_ on this_.id=this_1_.id 
       inner join AbstractEntity this_2_ on this_.id=this_2_.id 
       left outer join RawEndDeviceStatistic this_3_ on this_.id=this_3_.id 
       left outer join LinkStatistic l2_ on this_.linkStatistic_id=l2_.id 
       left outer join AbstractPerformanceStatistic l2_1_ on l2_.id=l2_1_.id 
       left outer join AbstractEntity l2_2_ on l2_.id=l2_2_.id 
       left outer join RawLinkStatistic l2_3_ on l2_.id=l2_3_.id 
       left outer join IPTStatistic i1_ on l2_.iptStat_id=i1_.id 
       left outer join AbstractPerformanceStatistic i1_1_ on i1_.id=i1_1_.id 
       left outer join AbstractEntity i1_2_ on i1_.id=i1_2_.id 
       left outer join RawIPTStatistic i1_3_ on i1_.id=i1_3_.id 

       where this_1_.dateTime between ? and ? 

       group by this_.deviceNo limit ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往事风中埋 2024-12-19 19:17:42

将别名放在 OVER 子句后面

SELECT salary
     , sum(salary) OVER (ORDER BY salary) AS my_alias
FROM   empsalary;

问题更新后编辑

您不能在 SELECT< 的同一级别引用列别名(“输出列”) /代码>。为此,您需要一个子选择或 CTE 。就像:

SELECT id, result, rank() OVER (ORDER BY result) AS rnk
FROM  (
    SELECT id, <complex expression> AS result
    FROM   tbl
    WHERE  <some condition>
    GROUP  BY id
    ) sub;

对于您的查询:

SELECT rank() OVER (ORDER BY deltahdlcOverruns) AS rnk
     , y1_
     , deltahdlcOverruns
FROM  (
    SELECT this_.deviceNo as y1_
        ,  (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
            JOIN   enddevicestatistic _dev_ USING (id)
            JOIN   linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
            JOIN   iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
            WHERE  this_.deviceNo=_dev_.deviceNo
            AND    _abs_.dateTime <= '3910-06-07 00:00:00.0'
            ORDER  BY _abs_.dateTime DESC
            LIMIT  1
           ) 
           - 
           (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
            JOIN   enddevicestatistic _dev_ USING (id)
            JOIN   linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
            JOIN   iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
            WHERE  this_.deviceNo=_dev_.deviceNo
            AND    _abs_.dateTime >= '3870-06-01 00:00:00.0' 
            ORDER  BY _abs_.dateTime
            LIMIT  1
           ) AS deltahdlcOverruns
    FROM   EndDeviceStatistic this_ 
    JOIN   AbstractPerformanceStatistic this_1_ USING (id)
    JOIN   AbstractEntity this_2_ USING (id)
    LEFT   JOIN RawEndDeviceStatistic this_3_ USING (id)
    LEFT   JOIN LinkStatistic l2_ ON this_.linkStatistic_id = l2_.id 
    LEFT   JOIN AbstractPerformanceStatistic l2_1_ ON l2_.id = l2_1_.id 
    LEFT   JOIN AbstractEntity l2_2_ ON l2_.id = l2_2_.id 
    LEFT   JOIN RawLinkStatistic l2_3_ ON l2_.id = l2_3_.id 
    LEFT   JOIN IPTStatistic i1_ ON l2_.iptStat_id = i1_.id 
    LEFT   JOIN AbstractPerformanceStatistic i1_1_ ON i1_.id = i1_1_.id 
    LEFT   JOIN AbstractEntity i1_2_ ON i1_.id = i1_2_.id 
    LEFT   JOIN RawIPTStatistic i1_3_ ON i1_.id = i1_3_.id 
    WHERE  this_1_.dateTime between ? and ? 
    GROUP  BY this_.deviceNo
    LIMIT  ?
) x;

我做了一些额外的语法简化

Place the alias behind the OVER clause:

SELECT salary
     , sum(salary) OVER (ORDER BY salary) AS my_alias
FROM   empsalary;

Edit after question update

You cannot reference a column alias (an "output column") at the same level of a SELECT. You need a subselect or a CTE for this. Like:

SELECT id, result, rank() OVER (ORDER BY result) AS rnk
FROM  (
    SELECT id, <complex expression> AS result
    FROM   tbl
    WHERE  <some condition>
    GROUP  BY id
    ) sub;

For your query:

SELECT rank() OVER (ORDER BY deltahdlcOverruns) AS rnk
     , y1_
     , deltahdlcOverruns
FROM  (
    SELECT this_.deviceNo as y1_
        ,  (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
            JOIN   enddevicestatistic _dev_ USING (id)
            JOIN   linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
            JOIN   iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
            WHERE  this_.deviceNo=_dev_.deviceNo
            AND    _abs_.dateTime <= '3910-06-07 00:00:00.0'
            ORDER  BY _abs_.dateTime DESC
            LIMIT  1
           ) 
           - 
           (SELECT _dev_.hdlcOverruns FROM abstractperformancestatistic _abs_ 
            JOIN   enddevicestatistic _dev_ USING (id)
            JOIN   linkstatistic _link_ ON _link_.id = _dev_.linkStatistic_id 
            JOIN   iptstatistic _ipt_ ON _ipt_.id = _link_.iptStat_id 
            WHERE  this_.deviceNo=_dev_.deviceNo
            AND    _abs_.dateTime >= '3870-06-01 00:00:00.0' 
            ORDER  BY _abs_.dateTime
            LIMIT  1
           ) AS deltahdlcOverruns
    FROM   EndDeviceStatistic this_ 
    JOIN   AbstractPerformanceStatistic this_1_ USING (id)
    JOIN   AbstractEntity this_2_ USING (id)
    LEFT   JOIN RawEndDeviceStatistic this_3_ USING (id)
    LEFT   JOIN LinkStatistic l2_ ON this_.linkStatistic_id = l2_.id 
    LEFT   JOIN AbstractPerformanceStatistic l2_1_ ON l2_.id = l2_1_.id 
    LEFT   JOIN AbstractEntity l2_2_ ON l2_.id = l2_2_.id 
    LEFT   JOIN RawLinkStatistic l2_3_ ON l2_.id = l2_3_.id 
    LEFT   JOIN IPTStatistic i1_ ON l2_.iptStat_id = i1_.id 
    LEFT   JOIN AbstractPerformanceStatistic i1_1_ ON i1_.id = i1_1_.id 
    LEFT   JOIN AbstractEntity i1_2_ ON i1_.id = i1_2_.id 
    LEFT   JOIN RawIPTStatistic i1_3_ ON i1_.id = i1_3_.id 
    WHERE  this_1_.dateTime between ? and ? 
    GROUP  BY this_.deviceNo
    LIMIT  ?
) x;

I made a few additional syntax simplifications.

放手` 2024-12-19 19:17:42

将窗口包装在周围的查询中:

SELECT salary, result OVER (ORDER BY result)
FROM (SELECT salary, (...expression...) AS result
      FROM empsalary
     ) x

wrap the windowing in a surrounding query:

SELECT salary, result OVER (ORDER BY result)
FROM (SELECT salary, (...expression...) AS result
      FROM empsalary
     ) x
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文