简体   繁体   English

CASE语句是否会丢失PostgreSQL中的别名范围?

[英]Does a CASE statement lose alias scope in PostgreSQL?

First of all, this SQL works: 首先,这个SQL有效:

select
    case
        when s.luserid > 0 then u.szusername
        when s.lgroupid > 0 then g.szgroup
        when s.lldapid > 0 then 'LDAP Group'
    end as name
from security s
left join users u on s.luserid = u.id
left join usergroups g on s.lgroupid = g.id
order by name

The above block is proving ordering by alias name works, as well as declaring alias name works while the term name is a reserved word, which is not relevant to the question 以上块由别名证明订货name的作品,以及宣布别名name工作而术语name是保留字,这是不相关的问题

My issue happens when I make a case statement with an alias in it: 当我在其中创建带有别名的case语句时,我的问题就出现了:

Pay attention to the alias useid 注意别名useid

select
    case
        when sa.luserid > 0 then sa.luserid
        when sa.lgroupid > 0 then sa.lgroupid
        when sa.lldapid > 0 then sa.lldapid
    end as useid,
from security s
left join users u on s.luserid = u.id
left join usergroups g on s.lgroupid = g.id
order by
        case
            when 'user selection' = 'all objects by user' then useid
            else s.lobjectid
        end

The text user selection is replaced by a parser with literal text before the SQL is run. 在运行SQL之前,文本user selection由具有文字文本的解析器替换。 Both the alias useid and s.lobjectid are type bigint . 别名useids.lobjectid都是bigint类型。

An error is thrown at when 'user selection' = 'all objects by user' then useid . when 'user selection' = 'all objects by user' then useid会引发错误。

Am I losing scope of the alias useid within the CASE statement? useid在CASE声明中丢失了别名useid范围? Why does this fail when I try to use the alias useid here. 当我尝试在此处使用别名useid时,为什么会失败。

By the way, this SQL works as well: 顺便说一句,这个SQL也可以:

select
    case
        when s.luserid > 0 then u.szusername
        when s.lgroupid > 0 then g.szgroup
        when s.lldapid > 0 then 'LDAP Group'
    end as name
from security s
left join users u on s.luserid = u.id
left join usergroups g on s.lgroupid = g.id
order by
        case
            when s.lobjectid > 0 then s.lobjectid
            else s.luserid
        end

The above block is proving that a CASE statement within an ORDER BY statement does work. 上面的块证明了ORDER BY语句中的CASE语句确实有效。 All debates over the logical operations of the above block of SQL is irrelevant to the question, for it is simply junk example SQL. 关于上述SQL块的逻辑操作的所有争论都与问题无关,因为它只是垃圾示例SQL。

What you are trying to do is not possible in Postgresql since it doesn't allow you to use an ALIAS within the same query as a field. 在Postgresql中你不能尝试做什么,因为它不允许你在同一个查询中使用ALIAS作为字段。 Different from Mysql where you can do it. 与Mysql不同,你可以在那里做到。

To solve your problem you either create your query as a subquery and then your alias will be a field therefore can be used as: 要解决您的问题,您可以将查询创建为子查询,然后您的别名将是一个字段,因此可以用作:

select useid, lobjectid from (
  select
      case
          when sa.luserid > 0 then sa.luserid
          when sa.lgroupid > 0 then sa.lgroupid
          when sa.lldapid > 0 then sa.lldapid
      end as useid,
      lobjectid
   from security s
  left join users u on s.luserid = u.id
  left join usergroups g on s.lgroupid = g.id
  ) as t
order by
        case
            when 'user selection' = 'all objects by user' then useid
            else lobjectid
        end

Or you can repeat the entiry case block 或者你可以重复entiry case块

  select
      case
          when sa.luserid > 0 then sa.luserid
          when sa.lgroupid > 0 then sa.lgroupid
          when sa.lldapid > 0 then sa.lldapid
      end as useid,
      lobjectid
   from security s
  left join users u on s.luserid = u.id
  left join usergroups g on s.lgroupid = g.id
order by
        case
            when 'user selection' = 'all objects by user' then 
                  case
                      when sa.luserid > 0 then sa.luserid
                      when sa.lgroupid > 0 then sa.lgroupid
                      when sa.lldapid > 0 then sa.lldapid
                  end
            else lobjectid
        end

Some engines will let you use the order number of the field on the select scope to the order by like: 某些引擎会让您使用选择范围上的字段的订单号,顺序如下:

select a, b, c from sometable order by 1, 2

Which means that this query will be ordered by the fields a and b 这意味着此查询将按字段ab排序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM