【问题标题】:Convert Coldfusion script in Oracle view with CASE and iteration使用 CASE 和迭代在 Oracle 视图中转换 Coldfusion 脚本
【发布时间】:2019-08-12 11:11:18
【问题描述】:

我创建了一个 Coldfusion 脚本,允许从数组中获取对象“单元”。

我的数据库有关于单位的视图。对于相同的单元键“ORG_ID”,它可以存在多行(在字段“origin”上有所不同)。 “起源”字段可以是“当前”、“历史”或“不同”。

+---------+---------+------------+------------+----------|
|  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),以便检索正确的单元版本。

但我不知道该怎么做,你能帮我吗?

提前感谢您的帮助。

赛博

【问题讨论】:

  • 我不是冷聚变专家,而是预言机。那么您能否编辑问题并分享示例数据和预期输出?
  • 嗨,我添加了所需的输出

标签: oracle coldfusion case


【解决方案1】:

我不知道 ColdFusion,但我想我理解其中的逻辑。优先级是当前 > 历史 > 不同。当有两个current 行或只有different 行时,不清楚哪一行是正确的,所以在这种情况下我用最小valid_from 标记行。如果不介意可以省略这个参数(从row_numberorder 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

dbfiddle demo

【讨论】:

  • 感谢您的回复。我现在用你的代码创建一个视图。我有另一个与此相关的问题。我有与单位相关的会议。多个会议可以有相同版本的单元。当我在会议和单位之间建立链接(基于 ORG_ID)时,我看到列表中的最后一个会议(字段 origin='current')的字段 correct_version 为 1。所有其他会议都有字段为 0。你能帮帮我吗?
  • 不确定我是否理解。如果您只想要具有正确版本的行,则在meeting.org_id = view_units.org_id and correct_version = 1 上进行连接。您还可以仅过滤“第一”行,例如 dbfiddle 中的行,并且在加入时根本不要使用此列。
  • 我通过更新查看与 meeting_id 链接的 meeting_unit_v,它似乎可以正常工作:select meeting_id, units.*, case when 1 = row_number() over ( partition by org_id, meeting_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 meeting_unit_v。但我有点失落。因此,据我所知,您能否请我将代码 `row_number() over ( partition by....`
  • 看起来正确。我唯一的疑问是如果有两个 current 值,你想要哪一行。如果你想要最新的,那么order by 的最后一部分应该是unit_valid_from DESC(降序)。如果你想首先使用升序,默认顺序。 Documentation 和 row_number() 的示例。
  • 我们的系统中只有一个“当前”或只有一个“其他”,但可能有多个“历史”按单位(因此按会议)。在最后一种情况下,只应选择与日期对应的第一个。
【解决方案2】:

我假设对于同一个 org_id 没有两行具有相同的来源,即使存在重复,也必须只有一条记录具有 VALID_FROM

以下是基于样本数据的解决方案。如果需要,请更改逻辑。

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;

干杯!!

【讨论】:

    猜你喜欢
    • 2014-02-04
    • 2021-10-13
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多