案例何时不纠正?

时间:2017-02-22 17:09:49

标签: oracle11g case-when

我们数据库中的表中的数据充满了错误。我正在尝试编写一个案例,when,then子句,它可能用正确的数据和另一个表替换错误。请记住,我有非常基本的权限,因此我无法编写任何比case更复杂的代码。我到目前为止的代码如下所示:

select distinct t.*,
case
    --** t.Corridor_RB  is full of bad entries
    when t.Corridor_RB <> s.Corridor_RB 
        then s.Corridor_RB --** what I want the data to be
        else s.Corridor_RB
        end as CorrectRb
from PROJECT_CORRS_RB_MILES t left join
corridors_grouped_tis s on 
t.Corridor_RB = s.Corridor_RB
where t.Direction <> 5
order by t.Corridor_RB

现在发生的是添加的列CorrectRb仍然是空的,如下面的屏幕截图所示:

enter image description here

那为什么会这样呢?例如,为什么C000001N没有从s.Corridor_RB更改为C000001E?空白空间不应该是来自s.Corridor_RB的数据吗?连接本身很好,它是一对一的。

以下是来自corridors_grouped_tis的数据:

TCR_CORRIDOR_ID CORRIDOR_RB SLICED
        C000001 C000001E    1
        C000002 C000002E    2
        C000003 C000003N    3
        C000004 C000004N    4
        C000005 C000005N    5
        C000006 C000006E    6
        C000007 C000007N    7
        C000008 C000008E    8
        C000009 C000009N    9
        C000010 C000010N    10
        C000011 C000011N    11
        C000012 C000012E    12

projects_corrs_rb_miles的输出如下所示:

         FED_ST_PRJ_NBR CONT_ID       ROUTE_NBR DIRECTION   CORRIDOR_RB BEG_TERMINI END_TERMINI
   1    HSIP-MT 1-6(76)384              11713           N-1 3   C000001E    384.0   386.6
   2    MT-NH 1-3(71)255                21216           N-1 3   C000001E    254.6   256.0
   3    HSIP-MT 1-6(76)384              11713           N-1 3   C000001E    384.0   386.6
   4    HSIP-MT 1-6(76)384              11713           N-1 3   C000001E    384.0   386.6
   5    MT-NH 1-3(71)255                21216           N-1 3   C000001E    254.6   256.0
   6    MT-NH 1-3(71)255                21216           N-1 3   C000001E    254.6   256.0
   7    HSIP 1-2(147)136                07C11           N-1 1   C000001N         
   8    NH 1-1(93)16                    08913           N-1 1   C000001N    16.0    44.8
   9    CBI-NHTSA-MT 1-1(79)45          03812           N-1 1   C000001N    44.9    48.6
  10    CBI-NHTSA-MT 1-1(79)45          03812           N-1 1   C000001N    44.9    48.6

1 个答案:

答案 0 :(得分:2)

目前你的案例表达有点无意义,因为两个分支都评估为同一个事物,s.Corridor_RB

但如果s行中t没有匹配行,并且因为您已包含加入条件

,则该值为空
t.Corridor_RB = s.Corridor_RB

如果它们相同,你只会得到一个匹配,即你将进入'else'分支。对于其他所有,s 上没有匹配项,因此s.Corridor_RB将为null。 (这也将进入'else',因为你无法将null与其他任何东西比作in / equality运算符。)

基本上,它只能为空,或与t.Corridor_RB完全相同。

你可能只是删除那个条件,它可能是一个内连接;但是你会发现st之间没有其他连接条件,所以你会在两个表之间得到一个笛卡尔积(交叉连接),这不太可能是你想要的。

您需要知道如何根据s中的其他一些列标识t中具有正确值的行。您不能将它基于您知道有错误条目的列 - 除非s只有一行,或者在坏值和良好值之间有映射,并且您加入或选择了错误的列。由于我们无法看到表格结构或数据,因此无法确定您需要加入的内容。

根据您添加的corridors_grouped_tis数据,看起来您想要根据根进行匹配,只需更改最后一个字符:

from PROJECT_CORRS_RB_MILES t left join
corridors_grouped_tis s on 
s.TCR_CORRIDOR_ID = substr(t.Corridor_RB, 1, length(t.Corridor_RB) - 1)

如果TCR_CORRIDOR_ID做了它看起来的样子;或许

substr(s.Corridor_RB, 1, length(s.Corridor_RB) - 1)
  = substr(t.Corridor_RB, 1, length(t.Corridor_RB) - 1)

或类似的,虽然这是对你的模式和如何匹配的假设。

将一个函数应用于列值通常会阻止使用该列上的任何索引,但如果这是一个小的查找表,它可能无关紧要,并且您可能无论如何都会遇到大部分行,使全扫描更好。如果有很多数据可以使用,你可以添加一个索引的虚拟列来执行子字符串,但这似乎有点过分了。

将您的样本数据演示为CTE:

with corridors_grouped_tis(TCR_CORRIDOR_ID, CORRIDOR_RB, SLICED) as (
  select 'C000001', 'C000001E', 1 from dual
  union all select 'C000002', 'C000002E', 2 from dual
  union all select 'C000003', 'C000003N', 3 from dual
  union all select 'C000004', 'C000004N', 4 from dual
  union all select 'C000005', 'C000005N', 5 from dual
  union all select 'C000006', 'C000006E', 6 from dual
  union all select 'C000007', 'C000007N', 7 from dual
  union all select 'C000008', 'C000008E', 8 from dual
  union all select 'C000009', 'C000009N', 9 from dual
  union all select 'C000010', 'C000010N', 10 from dual
  union all select 'C000011', 'C000011N', 11 from dual
  union all select 'C000012', 'C000012E', 12 from dual
),
project_corrs_rb_miles (FED_ST_PRJ_NBR, CONT_ID, ROUTE_NBR, DIRECTION, CORRIDOR_RB, BEG_TERMINI, END_TERMINI) as (
  select 'HSIP-MT 1-6(76)384', '11713', 'N-1', 3, 'C000001E', 384.0, 386.6 from dual
  union all select 'MT-NH 1-3(71)255', '21216', 'N-1', 3, 'C000001N', 254.6, 256.0 from dual
  union all select 'HSIP-MT 1-6(76)384', '11713', 'N-1', 3, 'C000001E', 384.0, 386.6 from dual
  union all select 'HSIP-MT 1-6(76)384', '11713', 'N-1', 3, 'C000001E', 384.0, 386.6 from dual
  union all select 'MT-NH 1-3(71)255', '21216', 'N-1', 3, 'C000001E', 254.6, 256.0 from dual
  union all select 'MT-NH 1-3(71)255', '21216', 'N-1', 3, 'C000001E', 254.6, 256.0 from dual
  union all select 'HSIP 1-2(147)136', '07C11', 'N-1', 1, 'C000001N', null, null from dual
  union all select 'NH 1-1(93)16', '08913', 'N-1', 1, 'C000001N', 16.0, 44.8 from dual
  union all select 'CBI-NHTSA-MT 1-1(79)45', '03812', 'N-1', 1, 'C000001N', 44.9, 48.6 from dual
  union all select 'CBI-NHTSA-MT 1-1(79)45', '03812', 'N-1', 1, 'C000001N', 44.9, 48.6 from dual
)
select t.*, s.Corridor_RB as CorrectRb
from PROJECT_CORRS_RB_MILES t left join
corridors_grouped_tis s on 
s.TCR_CORRIDOR_ID = substr(t.Corridor_RB, 1, length(t.Corridor_RB) - 1)
where t.Direction <> 5
order by t.Corridor_RB
/

FED_ST_PRJ_NBR         CONT_ ROU  DIRECTION CORRIDOR BEG_TERMINI END_TERMINI CORRECTR
---------------------- ----- --- ---------- -------- ----------- ----------- --------
MT-NH 1-3(71)255       21216 N-1          3 C000001E       254.6         256 C000001E
HSIP-MT 1-6(76)384     11713 N-1          3 C000001E         384       386.6 C000001E
HSIP-MT 1-6(76)384     11713 N-1          3 C000001E         384       386.6 C000001E
MT-NH 1-3(71)255       21216 N-1          3 C000001E       254.6         256 C000001E
HSIP-MT 1-6(76)384     11713 N-1          3 C000001E         384       386.6 C000001E
MT-NH 1-3(71)255       21216 N-1          3 C000001N       254.6         256 C000001E
HSIP 1-2(147)136       07C11 N-1          1 C000001N                         C000001E
NH 1-1(93)16           08913 N-1          1 C000001N          16        44.8 C000001E
CBI-NHTSA-MT 1-1(79)45 03812 N-1          1 C000001N        44.9        48.6 C000001E
CBI-NHTSA-MT 1-1(79)45 03812 N-1          1 C000001N        44.9        48.6 C000001E

10 rows selected.