使用 CASE 和迭代在 Oracle 视图中转换 Coldfusion 脚本
Convert Coldfusion script in Oracle view with CASE and iteration
我创建了一个 coldfusion 脚本,允许从数组中获取对象 "unit"。
我的数据库有关于单位的观点。对于同一个单元键"ORG_ID",它可以存在多行(在字段"origin"上有所不同)。字段 "origin" 可以是 "current"、"history" 或 "different".
+---------+---------+------------+------------+----------|
| ORG_ID | TITLE | VALID_FROM | VALID_TO | ORIGIN |
+---------+---------+------------+------------+----------|
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | other |
| 1234 | A.1 | 01/03/2016 | 31/12/3333 | current |
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | history |
| 5420 | A.2 | 01/01/2014 | 31/12/3333 | other |
| 9876 | A.3 | 01/03/2016 | 31/12/3333 | current |
| 9876 | B.3 | 01/03/2016 | 31/12/9999 | history |
| 5527 | A.1 | 01/03/2016 | 31/12/2199 | current |
| 5527 | D.2 | 01/01/2010 | 31/12/2015 | history |
| 5527 | A.1 | 01/01/2016 | 31/12/2199 | history |
| 6699 | E.5 | 01/01/2016 | 31/12/2017 | history |
| 6699 | A.4 | 01/01/2017 | 31/12/2018 | history |
+---------+---------+------------+------------+----------|
在这种情况下,例如这里我想要得到的结果:
+---------+---------+------------+------------+----------|--------------|
| ORG_ID | TITLE | VALID_FROM | VALID_TO | ORIGIN | CORRECT_VERS |
+---------+---------+------------+------------+----------|--------------|
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | other | 0 |
| 1234 | A.1 | 01/03/2016 | 31/12/3333 | current | 1 |
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | history | 0 |
| 5420 | A.2 | 01/01/2014 | 31/12/3333 | other | 1 |
| 9876 | A.3 | 01/03/2016 | 31/12/3333 | current | 1 |
| 9876 | B.3 | 01/03/2016 | 31/12/9999 | history | 0 |
| 5527 | A.1 | 01/03/2016 | 31/12/2199 | current | 1 |
| 5527 | D.2 | 01/01/2010 | 31/12/2015 | history | 0 |
| 5527 | A.1 | 01/01/2016 | 31/12/2199 | history | 0 |
| 6699 | E.5 | 01/01/2016 | 31/12/2017 | history | 0 |
| 6699 | A.4 | 01/01/2017 | 31/12/2018 | history | 0 |
+---------+---------+------------+------------+----------+--------------|
我的 Coldfusion 脚本: dataUnitArray 包含数组中的单位列表
<cftry>
<cfset hist = 0/>
<cfset unit = structNew() />
<cfloop index="i" from="1" to="#ArrayLen(dataUnitArray)#">
<cfif #dataUnitArray[i].ORIGIN# EQ "current">
<!--- Unit is current --->
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
return unit;
</cfscript>
<cfelse>
<cfif #dataUnitArray[i].ORIGIN# EQ "history">
<!--- Unit is history --->
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
</cfscript>
<cfset hist++ >
<cfelse>
<!--- Unit is different (other) --->
<cfif hist EQ 0>
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
</cfscript>
</cfif>
</cfif>
</cfif>
</cfloop>
<cfscript>
return unit;
</cfscript>
<cfcatch type="any">
<cfscript>
.....
</cfscript>
</cfcatch>
</cftry>
我的脚本运行正常。但是当我在大量数据上使用它时,我遇到了加载时间问题。这就是为什么我想直接在 ORACLE 中使用 CASE...WHEN 作为:
CASE
when ORIGIN = 'current' THEN 1
WHEN ORIGIN = 'history' THEN
CASE hist = 0 THEN ....
END
ELSE
0
END AS "IS_CORRECT_VERSION"
我想在视图中添加一个新列 "CORRECT_VERSION"(当版本正确时值为 0 或 1)以检索正确的单元版本。
但是我不知道该怎么做,你能帮我吗?
在此先感谢您的帮助。
塞布
我不知道 ColdFusion,但我想我理解其中的逻辑。优先级是当前 > 历史 > 不同。当有两个 current
行或只有 different
行时,不清楚哪一行是正确的,所以在这种情况下我将行标记为最小 valid_from
。如果你不在乎你可以省略这个参数(从row_number
的order by
子句中删除unit_valid_from
):
select units.*,
case when 1 =
row_number() over (
partition by org_id
order by case origin when 'current' then 1 when 'history' then 2 else 3 end,
unit_valid_from ) then 1 else 0 end as is_correct_version
from units
我假设没有两行具有相同来源的相同 org_id 并且即使存在重复项,也必须只有一个记录具有 VALID_FROM < SYSDATE < VALID_TO.
以下是基于示例数据的解决方案。如果需要,请更改逻辑。
SELECT
UNITS.*,
CASE
WHEN DENSE_RANK() OVER(
PARTITION BY ORG_ID
ORDER BY
CASE ORIGIN
WHEN 'current' THEN 1
WHEN 'history' THEN 2
ELSE 3
END
) = 1
AND TRUNC(SYSDATE) BETWEEN VALID_FROM AND VALID_TO THEN 1
ELSE 0
END AS IS_CORRECT_VERSION
FROM
UNITS;
干杯!!
我创建了一个 coldfusion 脚本,允许从数组中获取对象 "unit"。
我的数据库有关于单位的观点。对于同一个单元键"ORG_ID",它可以存在多行(在字段"origin"上有所不同)。字段 "origin" 可以是 "current"、"history" 或 "different".
+---------+---------+------------+------------+----------|
| ORG_ID | TITLE | VALID_FROM | VALID_TO | ORIGIN |
+---------+---------+------------+------------+----------|
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | other |
| 1234 | A.1 | 01/03/2016 | 31/12/3333 | current |
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | history |
| 5420 | A.2 | 01/01/2014 | 31/12/3333 | other |
| 9876 | A.3 | 01/03/2016 | 31/12/3333 | current |
| 9876 | B.3 | 01/03/2016 | 31/12/9999 | history |
| 5527 | A.1 | 01/03/2016 | 31/12/2199 | current |
| 5527 | D.2 | 01/01/2010 | 31/12/2015 | history |
| 5527 | A.1 | 01/01/2016 | 31/12/2199 | history |
| 6699 | E.5 | 01/01/2016 | 31/12/2017 | history |
| 6699 | A.4 | 01/01/2017 | 31/12/2018 | history |
+---------+---------+------------+------------+----------|
在这种情况下,例如这里我想要得到的结果:
+---------+---------+------------+------------+----------|--------------|
| ORG_ID | TITLE | VALID_FROM | VALID_TO | ORIGIN | CORRECT_VERS |
+---------+---------+------------+------------+----------|--------------|
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | other | 0 |
| 1234 | A.1 | 01/03/2016 | 31/12/3333 | current | 1 |
| 1234 | A.1 | 01/03/2016 | 31/12/9999 | history | 0 |
| 5420 | A.2 | 01/01/2014 | 31/12/3333 | other | 1 |
| 9876 | A.3 | 01/03/2016 | 31/12/3333 | current | 1 |
| 9876 | B.3 | 01/03/2016 | 31/12/9999 | history | 0 |
| 5527 | A.1 | 01/03/2016 | 31/12/2199 | current | 1 |
| 5527 | D.2 | 01/01/2010 | 31/12/2015 | history | 0 |
| 5527 | A.1 | 01/01/2016 | 31/12/2199 | history | 0 |
| 6699 | E.5 | 01/01/2016 | 31/12/2017 | history | 0 |
| 6699 | A.4 | 01/01/2017 | 31/12/2018 | history | 0 |
+---------+---------+------------+------------+----------+--------------|
我的 Coldfusion 脚本: dataUnitArray 包含数组中的单位列表
<cftry>
<cfset hist = 0/>
<cfset unit = structNew() />
<cfloop index="i" from="1" to="#ArrayLen(dataUnitArray)#">
<cfif #dataUnitArray[i].ORIGIN# EQ "current">
<!--- Unit is current --->
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
return unit;
</cfscript>
<cfelse>
<cfif #dataUnitArray[i].ORIGIN# EQ "history">
<!--- Unit is history --->
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
</cfscript>
<cfset hist++ >
<cfelse>
<!--- Unit is different (other) --->
<cfif hist EQ 0>
<cfscript>
unit.ORG_ID = #dataUnitArray[i].ORG_ID#;
unit.TITLE = #dataUnitArray[i].TITLE#;
unit.UNIT_VALID_FROM = #dateFormat(dataUnitArray[i].UNIT_VALID_FROM, 'DD/MM/YYYY')#;
unit.UNIT_VALID_TO = #dateFormat(dataUnitArray[i].UNIT_VALID_TO, 'DD/MM/YYYY')#;
unit.ORIGIN = #dataUnitArray[i].ORIGIN#;
</cfscript>
</cfif>
</cfif>
</cfif>
</cfloop>
<cfscript>
return unit;
</cfscript>
<cfcatch type="any">
<cfscript>
.....
</cfscript>
</cfcatch>
</cftry>
我的脚本运行正常。但是当我在大量数据上使用它时,我遇到了加载时间问题。这就是为什么我想直接在 ORACLE 中使用 CASE...WHEN 作为:
CASE
when ORIGIN = 'current' THEN 1
WHEN ORIGIN = 'history' THEN
CASE hist = 0 THEN ....
END
ELSE
0
END AS "IS_CORRECT_VERSION"
我想在视图中添加一个新列 "CORRECT_VERSION"(当版本正确时值为 0 或 1)以检索正确的单元版本。
但是我不知道该怎么做,你能帮我吗?
在此先感谢您的帮助。
塞布
我不知道 ColdFusion,但我想我理解其中的逻辑。优先级是当前 > 历史 > 不同。当有两个 current
行或只有 different
行时,不清楚哪一行是正确的,所以在这种情况下我将行标记为最小 valid_from
。如果你不在乎你可以省略这个参数(从row_number
的order by
子句中删除unit_valid_from
):
select units.*,
case when 1 =
row_number() over (
partition by org_id
order by case origin when 'current' then 1 when 'history' then 2 else 3 end,
unit_valid_from ) then 1 else 0 end as is_correct_version
from units
我假设没有两行具有相同来源的相同 org_id 并且即使存在重复项,也必须只有一个记录具有 VALID_FROM < SYSDATE < VALID_TO.
以下是基于示例数据的解决方案。如果需要,请更改逻辑。
SELECT
UNITS.*,
CASE
WHEN DENSE_RANK() OVER(
PARTITION BY ORG_ID
ORDER BY
CASE ORIGIN
WHEN 'current' THEN 1
WHEN 'history' THEN 2
ELSE 3
END
) = 1
AND TRUNC(SYSDATE) BETWEEN VALID_FROM AND VALID_TO THEN 1
ELSE 0
END AS IS_CORRECT_VERSION
FROM
UNITS;
干杯!!