wiz*_*g64 43 postgresql select
我正在将旧的基于 MS-Access 的系统转换为 PostgreSQL。在 Access 中,由 SELECT 组成的字段可以用作后面字段的等式的一部分,如下所示:
SELECT
samples.id,
samples.wet_weight / samples.dry_weight - 1 AS percent_water,
100 * percent_water AS percent_water_100
FROM samples;
Run Code Online (Sandbox Code Playgroud)
当我在 PostgreSQL 中这样做时,Postgres 抛出一个错误:
错误:“percent_water”列不存在。
通过从子选择中进行选择,我可以通过以下方式解决此问题:
SELECT
s1.id,
s1.percent_water,
100 * s1.percent_water AS percent_water_100
FROM (
SELECT
samples.id,
samples.wet_weight / samples.dry_weight - 1 AS percent_water
FROM samples
) s1;
Run Code Online (Sandbox Code Playgroud)
有没有像第一个代码块那样的快捷方式来绕过复杂的嵌套?我也可以说100 * (samples.wet_weight / samples.dry_weight - 1) AS percent_water_100,但这只是我的代码中进行的更大的数学系统中的一个小例子,其中有数十个更复杂的数学位相互叠加。我宁愿尽可能干净地做而不重复自己。
Erw*_*ter 36
有时这很不方便,但它是 SQL 标准行为,它可以防止歧义。您不能在同一SELECT列表中引用列别名。
有更短的语法选项:
SELECT s.*, s.percent_water * 100 AS percent_water_100
FROM (
SELECT id, wet_weight / NULLIF(dry_weight - 1, 0) AS percent_water
FROM samples
) s;
Run Code Online (Sandbox Code Playgroud)
您可以LATERAL在 Postgres 9.3+ 中使用连接:
SELECT s.id, s1.percent_water
, s1.percent_water * 100 AS percent_water_100
FROM samples s
, LATERAL (SELECT s.wet_weight / NULLIF(s.dry_weight - 1, 0) AS percent_water) s1;
Run Code Online (Sandbox Code Playgroud)
我添加了NULLIF()以防止被零除错误。
小智 6
我遇到了这样的事情,将 500 多行 Netezza 查询(又名修改后的 Postgres)迁移到 SQL Server。在 Netezza 中,允许将计算列别名用作下游引用中的值。
我的解决方法是将 CROSS APPLY 与相关子查询一起使用。它的美妙之处在于根本不需要更改原始查询中对列别名的大量引用。
使用来自 OP 的查询,该CROSS APPLY方法将类似于:
SELECT
s.id,
x.percent_water,
100 * x.percent_water AS percent_water_100
FROM samples AS s
CROSS APPLY (SELECT s.wet_weight / s.dry_weight - 1 AS percent_water ) x ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54032 次 |
| 最近记录: |