案例 什么时候不纠正?

Case When not correcting?

我们数据库中 table 的数据充满了错误。我正在尝试编写一个 case, when, then 子句,该子句可能会用正确的数据替换错误,并且来自另一个 table。请记住,我拥有非常基本的权限,所以我不能在任何时候编写比大小写更复杂的代码。我目前的代码如下所示:

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 仍然充满空值,如下面的屏幕截图所示:

那么为什么会这样呢?例如,为什么 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

目前您的 case 表达式有点毫无意义,因为两个分支的计算结果相同,s.Corridor_RB

但是,如果 s 中没有与 t 行匹配的行,并且因为您包含了连接条件

,那将为 null
t.Corridor_RB = s.Corridor_RB

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

本质上,它只能为空,或者与 t.Corridor_RB.

完全相同

您可以只删除该条件,作为内部联接可能没问题;但是随后您会发现 st 之间没有其他连接条件,因此您将在两个 table 之间获得笛卡尔积(交叉连接),这不太可能随心所欲

您需要知道如何根据 t 中的某些其他列来识别 s 中具有正确值的行。您不能将它基于您知道有错误条目的列 - 除非 s 只有一行,或者在错误值和良好值之间有映射,并且您加入或选择了错误的列。由于我们看不到 table 结构或数据,因此无法判断您真正需要的连接是什么。


根据你添加的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)

或类似的,尽管这是对您的模式以及如何匹配的假设。

将函数应用于列值通常会阻止使用该列上的任何索引,但如果这是一个小查找 table 它可能无关紧要,你很可能会命中无论如何,很大一部分行,使完整扫描更可取。如果有大量数据要处理,您可以添加一个索引虚拟列来处理子字符串,但在这里似乎有点过分了。

使用示例数据作为 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.