SQL CASE 语句检查 Field 中的多个拼写和 return 如果找到相同的值?

SQL CASE statement to check multiple spellings in Field and return same value if found?

我正在创建一个 Oracle 数据库转换脚本,以将记录从旧的单数 table 移动到具有更多字段以及 child/reference tables 以获得更好的完整性。当我在 Table1 中 运行 a SELECT DISTINCT for VENDOR 时,我得到了 58 个结果。下面是一个例子,说明这些结果对于相同的含义有多么不同:

在我的参考 table 中,我已经为这个特定值设置了一条记录 "World Wide Technology, Inc."

有没有一种方法可以指定(也许是 CASE 语句?)当这些不同的拼写用于 return 我在我的 child table 中的值时 (例如)"World Wide Technology, Inc."?

这个 Table 是最简单的 child table 处理因为它只有 17 个不同的值我插入它,而 Table1 有 58 个不同的值行 returning。到目前为止我有:

INSERT INTO Table2 (VendorID, col2, col3, col4, etc...)
SELECT T3.ID, T1.col7, T1.col8, T1.col9, etc...
FROM Table1 T1
INNER JOIN Table3 T3 ON LTRIM(UPPER(T1.Vendor)) = UPPER(T3.Vendor_Name)

我在 Table1 中有 1349 条记录,但这(仅 SELECT 部分)只有 returning 418 条记录。

有谁知道如何解决我在这里的问题?

我认为您正在寻找 LEFT OUTER JOIN。然后假设您有一个映射 table Table4,其中列 wrong 表示您想要的实体的拼写错误,right 表示正确的拼写。那么:

INSERT INTO Table2 (VendorID, col2, col3, col4, etc...)
SELECT COALESCE ( T4.RIGHT, T3.ID, T1.Vendor ), T1.col7, T1.col8, T1.col9, etc...
FROM Table1 T1
LEFT OUTER JOIN Table3 T3 ON LTRIM(UPPER(T1.Vendor)) = UPPER(T3.Vendor_Name)
LEFT OUTER JOIN Table4 T4 ON LTRIM(UPPER(T1.Vendor)) = UPPER (T4.WRONG)

JOIN 将包含来自 T1 的所有记录和来自 T3T4 的结果,仅当满足 JOIN 中任一匹配条件时。如果不满足条件,所有 T3/T4 列在查询结果中将显示为 NULL。因此,您可以在 SELECT 子句中使用 COALESCE 表示:如果有 T4.right,则使用它,否则如果有 T3.ID,则使用它,否则,使用 T1.Vendor.

如果您没有也不想创建映射 table,案例方法将类似于您之前关于日期的问题。要转换所有值,您需要执行以下操作:

select case
  when vendor in (
    'WWT',
    ' WWT',
    'Worldwide Technologies',
    ' Worldwide Technologies',
    ' WorldWide Technology',
    'World Wide Technology'
  ) then 'World Wide Technology, Inc.'
  when t1.vendor in (
    'ACME',
    ' acme'
  ) then 'ACME, Inc.'
  ... other groups of original values with their new equivalents
  else null
  end as vendor_name
from t1;

在你的情况下,你可能会硬编码新的 vendor_id 而不是名称,否则你只需要重新加入 t3 以根据你的映射获取 ID姓名:

INSERT INTO Table2 (VendorID, col2, col3, col4, etc...)
SELECT case
  when t1.vendor in (
    'WWT',
    ' WWT',
    'Worldwide Technologies',
    ' Worldwide Technologies',
    ' WorldWide Technology',
    'World Wide Technology'
  ) then 42 -- ID for 'World Wide Technology, Inc.'
  when t1.vendor in (
    'ACME',
    ' acme'
  ) then 76 -- ID for 'ACME, Inc.'
  ... other groups of original values with their new equivalents
  else null
  end as vendor_id, T1.col7, T1.col8, T1.col9, etc...
FROM Table1 T1;

如果您有很多不同的值,这些值仅因大小写和 leading/trailing 空格而异,您可以减少要检查的值的数量,例如:

select case
  when trim(upper(t1.vendor)) in (
    'WWT',
    'WORLDWIDE TECHNOLOGIES',
    'WORLD WIDE TECHNOLOGY'
  ) then 42 -- ID for 'World Wide Technology, Inc.'
  when trim(upper(t1.vendor)) in (
    'ACME'
  ) then 76 -- ID for 'ACME, Inc.'
  else null
  end as vendor_name
from t1;

您还可以删除标点符号等。基本上,您首先用来标识不同值的任何查询表达式都必须与您在 case 表达式中使用的任何内容相匹配。因此,在这个例子中,而不是你原来的 SELECT DISTINCT VENDOR FROM Table1 有 58 个值,你会做 SELECT DISTINCT TRIM(UPPER(VENDOR)) FROM Table1 这会给你更少,减少(稍微)手动匹配每个值到一个新的供应商 ID 的痛苦。

如果你想在 case 映射中使用描述,你可以加入你的新查找 table,然后在 join 子句中做 case:

select t1.vendor, t3.vendor_id, t3.description
from t1
left join t3 on t3.description = case
  when trim(upper(t1.vendor)) in (
    'WWT',
    'WORLDWIDE TECHNOLOGIES',
    'WORLD WIDE TECHNOLOGY'
  ) then 'World Wide Technology, Inc.'
  when trim(upper(t1.vendor)) in (
    'ACME'
  ) then 'ACME, Inc.'
  else null
  end;

VENDOR                    VENDOR_ID DESCRIPTION               
------------------------ ---------- ---------------------------
 Worldwide Technologies          42 World Wide Technology, Inc.
 World Wide Technology           42 World Wide Technology, Inc.
WWT                              42 World Wide Technology, Inc.
 AcMe                            76 ACME, Inc.                 

等显然,这只是一个演示。我已经将其设为左连接,因此如果您有一个尚未映射的值,或者在描述中有错字等,它将尝试插入一个空值。然后,您可以查找空值并根据需要填充它们,或者对新的(大概是外键)列进行非空约束,这样它就不会让您在没有匹配项的情况下插入 - 但这可能过于严格,再次取决于您的实际数据。