【问题标题】:SQL Server : CASE when any of 10 columns agreeSQL Server:10列中的任何一列都同意的情况
【发布时间】:2016-05-10 05:43:43
【问题描述】:

我在一个表中有 10 列(项目),在另一个表中有 10 个。

我想确定一个表中的任何一个列/项目与另一个表中的任何一个列/项目匹配的情况。

我下面的代码是针对三个项目的,效率低下 - 如何针对 10 列/项目进行修改?

CASE
   WHEN (t1.[item1] = t2.[item1] OR t1.[item1] = t2.[item2] OR t1.[item1] = t2.[item3])
     OR (t1.[item2] = t2.[item2] OR t1.[item2] = t2.[item1] OR t1.[item2] = t2.[item3])
     OR (t1.[item3] = t2.[item3] OR t1.[item3] = t2.[item1] OR t1.[item3] = t2.[item2])
     THEN 1
   ELSE 0 
END AS [match]

【问题讨论】:

  • 请使用示例数据和所需结果编辑您的问题。
  • 规范化表格,使项目字段成为自己的子字段,然后您只需匹配一个字段。

标签: sql sql-server-2008 case


【解决方案1】:

我不知道这是否更有效,但写起来更简单:使用 IN 而不是相等测试。例如,

WHEN t1.item1 IN (T2.item1, T2.item2, T2.item3)

为了更有效的方式,(但涉及更多的过程)使用 UNPIVOT 将每个列值转换为每个表的单独行。如果新表仅用于此过程,则在当前键列以及项目列上放置聚集索引。从这里,您可以执行 JOIN 来查找匹配值。

【讨论】:

  • 效率不高; x IN (y,z) 等价于 x = y OR x = z。但它更具可读性。
【解决方案2】:

如果您不想规范化表格,您可以使用“IN”语法并在程序中生成案例条件:

SELECT tbl1.id, tbl1.a, tbl1.b, tbl1.c,
    MAX(CASE WHEN tbl1.a IN (tbl2.a,tbl2.b,tbl2.c) OR tbl1.b IN (tbl2.a,tbl2.b,tbl2.c) OR tbl1.c IN (tbl2.a,tbl2.b,tbl2.c) THEN 1 ELSE 0 END) AS match
FROM (VALUES (1,1,2,3),(2,2,3,4),(3,3,4,5)) AS tbl1(id,a,b,c),
(VALUES (1,6,7,8),(2,7,8,9),(3,1,5,8)) AS tbl2(id,a,b,c)
GROUP BY tbl1.id,tbl1.a,tbl1.b,tbl1.c

【讨论】:

    【解决方案3】:

    下面是一些示例代码,用于获取 2 个包含多个列的表作为项目值,将它们取消透视,使项目值位于单个列中,然后加入 2 个新数据集以仅获取匹配项:

    Select T1.ObjID,T1.ItemValue
    From (
            Select objID,ItemValue
            from T1
                unpivot 
                (ItemValue FOR ItemValues IN (I1, I2, I3, I4)) As IVs
        )T1
    Inner join 
        (Select objID,ItemValue
            from T2
                unpivot 
                (ItemValue FOR ItemValues IN (I1, I2, I3, I4)) As IVs
        )T2
        on T1.ObjID = T2.ObjID 
            and T1.ItemValue = T2.ItemValue
    

    要仅返回指示匹配位置的 ID,您可以使用 Select Distinct ObjID 而不是 Select ObjID,ItemValue

    为了提高速度,创建实际的表来保存数据并确保 ObjID 和 ItemValue 列上有索引。我会将此表设为聚集键,在这种情况下,在加载数据时,请确保数据已排序。例如

    Insert Into T1_withIndex (ObjID, ItemValue) 
    Select objID,ItemValue
        from T1
            unpivot 
            (ItemValue FOR ItemValues IN (I1, I2, I3, I4)) As IVs
        Order by ObjID, ItemValue
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多