【问题标题】:Selecting a default value from table if row does not exist如果行不存在,则从表中选择默认值
【发布时间】:2014-11-10 03:29:43
【问题描述】:

我有两张桌子 - 具有列 ID、代码、ProviderId 的表记录 带有 Code、Number、ProviderId 列的表格代码

样本数据:

表格记录

 ID             Code         ProviderId
 1              ABC           1 
 2              DEF           2
 3              XYZ           1
 4              PQR           2

表格代码

 Code       Number     ProviderId
 ABC        1111        1
 Default    9999        1 
 XYZ        2222        2
 Default    4444       2

记录表中的所有行都会有一个代码。 代码 表将有一组代码与其他信息一起定义。记录表中的所有代码都不必在代码表中都有一个条目。对于记录表中的代码,如果存在对应的值则选择相同的,否则需要根据ProviderID列选择默认代码。

我的预期结果是:

ID      Code     Number
-------------------------
1       ABC      1111
2       DEF      9999 -> Picked up the default for ProviderId 1
3       XYZ      2222
4       PQR      4444 -. Picked up the default for ProviderId 2

我能够使用左外连接将记录添加到表变量中,然后再次执行内连接来实现这一点。 我想知道我是否可以通过一次选择来实现这一目标。

【问题讨论】:

  • Ben10 :但 DEF 的 providerID = 2。因此它不应该返回 ProviderId 2 的默认值,即 4444

标签: sql-server


【解决方案1】:

您可以通过left joins 做到这一点:

select r.id, r.code, coalesce(c.number, cd.number) as number:
from records r left join
     codes c
     on r.code = c.code left join
     codes cd
     on r.providerid = c.providerid and c.code = 'Default';

也就是说,查找两个值。如果匹配,请根据code 选择一个;否则,使用默认值。

【讨论】:

    【解决方案2】:

    我认为,您的“DEF”或“PQR”条目是错误的,其中一个应该有“Providerid”为 1。我从您的数据中准备了一个样本。

    使用@Gordon 的一些代码。但逻辑不同。

    declare @records table(id int, code varchar(50), providerid int)
    declare @code table(code varchar(50), number int, providerid int)
    
    insert into @records values (1,'ABC',1), (2,'DEF',2),(3,'XYZ',1),(4,'PQR',2)
    
    insert into @code values ('ABC',1111,1 ), ('DEFAULT',9999, 1) , ('XYZ',2222,2) , ('Default', 4444, 2)
    
    --your data in wrongly entered , that why the 'DEF' show the wrong thing below.
    select 
        id, r.code ,
         case 
            when ISNULL(c.code , '') = '' 
            then c1.number
            else c.number
        end
    from 
        @records r
        left outer join @code c on r.code = c.code
        left outer join @code c1 on r.providerid = c1.providerid and LOWER( c1.code) = 'default'
    
    --if the default entry is multiple times, then good to use sub-query with top   
    select 
        id, r.code ,
        case 
            when ISNULL(c.code , '') = '' 
            then ( select top 1 number from @code c1 where r.providerid = c1.providerid and LOWER( c1.code) = 'default' )
            else c.number
        end
    from 
        @records r
        left outer join @code c on r.code = c.code
    

    【讨论】:

      【解决方案3】:

      试试这个.. 正如其他人所提到的 'PQR' 您的输出中的条目是错误的。它不应该是'9999'。应该是'4444'

      SELECT a.ID,b.Code,b.Number
      FROM   Records a
             JOIN code b
               ON a.Code = b.Code
      UNION ALL
      SELECT a.ID,a.Code,b.Number
      FROM   Records  a
             JOIN code b
               ON a.ProviderId = b.ProviderId
      WHERE  NOT EXISTS(SELECT 1
                        FROM   Code aa
                        WHERE  aa.Code = a.Code)
             AND b.Code = 'default' 
      

      【讨论】:

        【解决方案4】:
        SELECT A.ID,A.Code,B.Number,A.ProviderId
        FROM   #Source A
        JOIN   #Code B ON A.Code = B.Code
        UNION
        (SELECT A.ID,A.Code,B.Number,A.ProviderId
        FROM   #Source A
        JOIN   #Code B ON A.Code != B.Code
                      AND B.Code = 'Default'
        WHERE  A.Code NOT IN (SELECT A.Code
                              FROM   #Source A
                              JOIN   #Code B ON A.Code = B.Code)
           AND A.ProviderId = B.ProviderId )
        

        试试这个

        【讨论】:

          猜你喜欢
          • 2019-03-05
          • 1970-01-01
          • 1970-01-01
          • 2017-09-20
          • 2022-12-15
          • 2021-10-27
          • 2017-05-18
          • 2012-03-22
          • 1970-01-01
          相关资源
          最近更新 更多