Sql server SQL Server—创建数据映射/聚合的有效方法

Sql server SQL Server—创建数据映射/聚合的有效方法,sql-server,dictionary,join,Sql Server,Dictionary,Join,假设我在SQL Server(2012)中有下表: 我希望创建一个映射表,将Col1-Col4中的特定值映射到特定标签。例如,它可以如下所示: MyMaps: Col1: Col2: Col3: Col4: Label: a <null> <null> d Label1 <null> b <null> d Label2 它是有效的,但我很好奇这

假设我在SQL Server(2012)中有下表:

我希望创建一个映射表,将
Col1
-
Col4
中的特定值映射到特定标签。例如,它可以如下所示:

MyMaps:
Col1:    Col2:    Col3:    Col4:    Label:
a        <null>   <null>   d        Label1
<null>   b        <null>   d        Label2    
它是有效的,但我很好奇这是一种很好的方法,还是有更好/更有效的方法来创建映射,因为MyTable是一个相当大的表


有什么想法/建议吗?

有多种方法可以做到这一点,比如选择第一个匹配项,或者使用复杂连接,或者编写带有循环的复杂TSQL等等

如果是一张小桌子,那就没关系。对于大型表,您可能需要一个映射表来定义MyTable如何映射到MyMaps(将其重命名为MyTableLabel)。您可以在执行插入或更新操作时计算映射


或者,如果MyMaps是提前知道的,即查找表,则可以定义所有组合,例如(a、b、c、d、标签1),(null、b、c、null、label2),(null、null、null、d、label3)。这样,您就可以加入,而不必执行COALESCE和ISNULL

因为MyTable有cols ABCD,如果MyMaps包含(null,b,c,null)Label3怎么办?这是一种匹配,Label1也是。如何选择正确的标签?此外,根据您的联接条件,它在大型表上的性能也不好,因为您使用的是COALESCE和ISNULL。如果在
MyTable
table的一行中找到两个映射,会发生什么情况?@KMC&Siyavash,这一点很好。我只是不知道该怎么做,根据我的数据,我认为情况不会如此。。。。我真的不知道如何完成这种映射。@JohnBustos您的查询与示例中的两行都匹配,这就是您想要的吗?如果不是,您将使用什么标准来确定映射到Label1而不是Label2,或者反之亦然?@SteveFord,正如我之前所说,我没有更好的方法来创建这个映射表。我已经创建了单独的查询,以在事后检查重复的映射,但这是创建所需映射的唯一方法。不过,我对不同的架构非常开放。我希望我能提前完成映射-这绝对是最有意义的不幸的是,我不能,因为业务用户希望能够通过Maps表动态地定义规则。我只是希望有一个更好的映射模式/实现,我可以使用比这一个更好的总体。。。有什么想法吗?现在,只需使用我示例中的子查询。它将使用第一场比赛。您应该询问业务用户如何处理多个匹配。对于ex),是否应首先使用匹配最多列的匹配项?当您从业务用户那里获得更多需求时,您可以优化代码。例如)他们可能会给你一个非功能性的要求,即查询必须在2秒内返回结果。我想人们都同意你的解决方案是最好的——我在这里一直坚持并希望得到某种形式的欢呼,但非常感谢你对这个问题的关注和回答!对不起,约翰。如果不进一步了解您的内部系统(即表架构和索引)、用户需求和系统过程(即这些表是如何填充的以及来自哪些系统),就很难提出任何其他解决方案。如果你能在不违反公司政策的情况下透露更多信息,我相信这里的每个人都会再次尝试。祝你好运。
MyMaps:
Col1:    Col2:    Col3:    Col4:    Label:
a        <null>   <null>   d        Label1
<null>   b        <null>   d        Label2    
SELECT
   MyMaps.Label
   ,MyTable.Val1
    ...
   ,MyTable.Valn
FROM
   MyTable
   INNER JOIN MyMaps
   ON ISNULL(MyTable.Col1, '') = COALESCE(MyMaps.Col1, MyTable.Col1, '')
   AND ISNULL(MyTable.Col2, '') = COALESCE(MyMaps.Col2, MyTable.Col2, '')
   AND ISNULL(MyTable.Col3, '') = COALESCE(MyMaps.Col3, MyTable.Col3, '')
   AND ISNULL(MyTable.Col4, '') = COALESCE(MyMaps.Col4, MyTable.Col4, '')
  SELECT

           t.*,
           Label = ( 
                    --since there can be multiple matches, this is where you apply your rules
                     select top 1 label
                     from  MyMaps
                     where ISNULL(MyTable.Col1, '') = COALESCE(MyMaps.Col1, MyTable.Col1, '')
                       AND ISNULL(MyTable.Col2, '') = COALESCE(MyMaps.Col2, MyTable.Col2, '')
                       AND ISNULL(MyTable.Col3, '') = COALESCE(MyMaps.Col3, MyTable.Col3, '')
                       AND ISNULL(MyTable.Col4, '') = COALESCE(MyMaps.Col4, MyTable.Col4, '')
                    )

    FROM MyTable t