python - Oracle SQL 计算列 - 如何在同一查询的另一个计算中引用计算列?
问题描述
我想在同一个查询中的另一个计算中使用计算列。但据我所知,Oracle SQL 似乎不允许我这样做。这些似乎是一个简单的数据操作,我可以在 Python 中轻松完成,但 Oracle SQL 似乎具有挑战性。
例如:
桌子
日期 | 值1 | 价值2
所需的查询功能
SELECT
date,
value1,
value2,
(value2 * value1) AS value_calculated
(value_calculated * 100) AS value_calculated_2
(value_calculated_2 * 1000) AS value_calculated_3
FROM table
如果这是不可能的,我认为 Oracle 应该将其内置到他们的软件中。
在其他 Stack Overflow 问题/响应中,CROSS APPLY 出现了。这对我不起作用,因为我需要创建 10-20 个计算列(所有这些列都引用其他计算列)。
我可以创建一个简单的 PL/SQL 函数来将它们指定为用于其他列计算的对象吗?
更新问题:
这是我正在做的事情的完整代码,使用 Oracle Cloud Financials 19C
WITH segment_desc AS(
SELECT DISTINCT
flex_value,
description
FROM
fnd_flex_values_vl
WHERE description NOT IN('Default')
),
balances_calc AS(
SELECT
gl_balances.period_name,
gl_ledgers.ledger_id,
gl_ledgers.name,
gl_ledgers.currency_code||'-'||gl_balances.currency_code
func_ent_curr_pair,
gl_code_combinations.code_combination_id,
gl_code_combinations.segment1,
gl_code_combinations.segment2,
segment_desc.description center_description,
gl_code_combinations.segment3,
gl_code_combinations.segment4,
gl_code_combinations.segment5,
gl_balances.currency_code ent_curr_cd,
-- balance logic swap functional/entered if ent=func
CASE
WHEN gl_balances.currency_code = gl_ledgers.currency_code
THEN NVL(gl_balances.begin_balance_dr_beq,0) -
NVL(gl_balances.begin_balance_cr_beq,0) -- return functional "beq"
ELSE NVL(gl_balances.begin_balance_dr,0) -
NVL(gl_balances.begin_balance_cr,0) -- return entered "balances_cr/dr"
END
ent_beg_balance,
-- activity logic swap functional/entered if func=ent
CASE
WHEN gl_balances.currency_code = gl_ledgers.currency_code
THEN NVL(gl_balances.period_net_dr_beq,0) -
NVL(gl_balances.period_net_cr_beq,0) -- return functional "beq"
ELSE NVL(gl_balances.period_net_dr,0) -
NVL(gl_balances.period_net_cr,0) -- return entered "balances_cr/dr"
END
ent_activity,
gl_ledgers.currency_code func_curr_cd,
NVL(gl_balances.begin_balance_dr_beq,0) -
NVL(gl_balances.begin_balance_cr_beq,0) func_beg_balance,
NVL(gl_balances.period_net_dr_beq,0) -
NVL(gl_balances.period_net_cr_beq,0) func_activity,
-- if statement currency equals
CASE
WHEN gl_balances.currency_code = gl_ledgers.currency_code
THEN 'TRUE'
ELSE 'FALSE'
END
entered_equals_functional,
gl_balances.translated_flag
FROM
gl_balances, gl_code_combinations, gl_ledgers, segment_desc
WHERE
1 = 1
AND gl_code_combinations.chart_of_accounts_id = '2001'
AND (gl_balances.translated_flag IN ('N','R') OR
gl_balances.translated_flag IS NULL)
AND gl_balances.code_combination_id =
gl_code_combinations.code_combination_id
AND gl_ledgers.ledger_id = gl_balances.ledger_id
AND segment_desc.flex_value (+) = gl_code_combinations.segment2
),
balances_calc_test AS(
SELECT
balances_calc.period_name,
balances_calc.segment1,
balances_calc.segment2,
balances_calc.segment3,
balances_calc.segment4,
**calc_column.func_end_balance,**
**calc_column_2.custom_calc**
FROM balances_calc
**CROSS APPLY(SELECT func_beg_balance + func_activity AS func_end_balance
FROM balances_calc) calc_column**
**CROSS APPLY(SELECT func_end_balance - ent_activity AS custom_calc FROM
balances_calc) calc_column_2**
)
SELECT * FROM balances_calc_test
这会在查询中返回错误
我在calc_column.func_end_balance列中得到重复值。
我应该使用 WHERE 语句加入吗?
同样,我认为需要有一个更简单的解决方案来进行派生列计算。Python Pandas 可以在 2 秒内完成此操作。
解决方案
这是标准的 SQL 功能,它的定义是有充分理由的:数据库不需要以select
任何顺序评估表达式。因此,没有“之前”别名可供查看。
正常的解决方案是 CTE 或子查询:
SELECT t.*,
(value_calculated_2 * 1000) AS value_calculated_3
FROM (SELECT t.*,
(value_calculated * 100) AS value_calculated_2
FROM (SELECT date, value1, value2,
(value2 * value1) AS value_calculated
FROM . . .
) t
) t
推荐阅读
- c - system() 如何影响 x64 linux 中的堆栈?
- c++ - 我收到一个错误,无法将 int* 转换为 int,但我无法弄清楚究竟是什么原因造成的
- tensorflow - 如何加载 export_inference_graph.py 保存的训练模型?
- aws-glue - 无法从 AWS Glue 启动现有 SageMaker Notebook
- javascript - 使用 JWT 身份验证对 DRF 的 axios 请求失败
- asp.net-mvc - 将数据列表从组件发布到新组件并在 Blazor 中呈现新组件
- python - eli5 permuter.feature_importances_ 返回全零
- reactjs - 使用 React Hook 表单 React Dropzone
- java - 如何在没有 Class.forName 或 DriverManager.registerDriver 的情况下自动加载 JDBC Wrapper Driver 类
- python - 使用 PyTorch,当我有填充时,我的 Conv1d 维度如何减少?