【发布时间】:2015-04-27 21:43:01
【问题描述】:
首先,这条 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
上面的代码块证明了别名 name 的排序有效,以及声明别名 name 有效,而术语 name 是保留字,与问题无关
我的问题发生在我使用别名的 case 语句时:
注意别名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
在运行 SQL 之前,文本 user selection 被解析器替换为文字文本。别名useid 和s.lobjectid 都是bigint 类型。
when 'user selection' = 'all objects by user' then useid 处抛出错误。
我是否在 CASE 语句中丢失了别名 useid 的范围?
为什么我在这里尝试使用别名 useid 时会失败。
顺便说一句,这个 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
上面的代码块证明了ORDER BY 语句中的CASE 语句确实有效。所有关于上述 SQL 块的逻辑操作的争论都与问题无关,因为它只是垃圾示例 SQL。
【问题讨论】:
-
它们是不同的类型。为什么不只是
order by s.lobjectid, name? (您不能按表达式name排序,因此您必须使用子选择或重复 case 表达式) -
如果您没有注意到,第一个 SQL 块可以正常工作,而不管
name是否被保留。此外,这些只是示例。我已经更新了问题(特别是第二个 SQL 块,即失败的那个)以更匹配我的实际 SQL。对于之前存在的可怕示例 SQL,我感到非常抱歉。 -
你说“我的问题发生在我做一个包含变量的case语句时:”变量在哪里?我什么都看不到。
-
@ypercube 变量是
useid,我在select语句中定义了 -
啊,那是别名,不是变量。无论如何,您不能在
ORDER BY的CASE表达式中使用别名(如name)。您可以重复整个case when s.luserid > 0 then u.szusername when s.lgroupid > 0 then g.szgroup when s.lldapid > 0 then 'LDAP Group' end表达式或将整个表达式包装在子查询(派生表或 cte)中。
标签: sql postgresql sql-order-by