动态比较多行的所有列

时间:2016-03-28 20:50:00

标签: sql sql-server unions except

在SQL Server 2008R2中: 我想要做的是从同一个表中获取多行并进行比较,以得出最完整的行。我需要列查找是动态的,因为列可以更改,并且访问我正在编写的脚本在生活时不会轻易改变。该表有277列(并且正在计数),但我们暂时尝试简化:

REC  FIRST  LAST   MIDDLE    CITY     STATE    CTRY
1    John   Doe              Phoenix  UNK         
2    John   Doe    Quincy             AZ
3    J      Doe              Phoenix  AZ       USA  

我希望能够选择一个"主人"对于此示例,我们假设REC 1,并且值为NULL,从下一行中选择值,如果为null,则为所有选定行选择下一行等。 BONUS 如果我不仅可以覆盖NULLS,而且值=' UNK'这将是我的下一步。理想情况下,上述的组合记录将如下所示:

REC  FIRST  LAST   MIDDLE    CITY     STATE    CTRY
1    John   Doe    Quincy    Phoenix  AZ       USA

我玩过除了各种UNIONS之外的玩具,但由于这种动态因素阻碍了我的进步,所以它还没有走出大门。

如果无法按照上面的要求对多行执行此操作,我很乐意比较1到2,然后比较1到3。

修改 我想要做的是动态(并且动态地,我的意思是说列和列数可能因事件而异)创建:

create table #Something
(
    REC int
    , FIRSTName varchar(10)
    , LASTName varchar(10)
    , MIDDLE varchar(10)
    , CITY varchar(10)
    , STATE varchar(10)
    , CTRY varchar(10)
)

insert #Something
select 1, 'John', 'Doe', NULL, 'Phoenix', 'UNK', null union all
select 2, 'John', 'Doe', 'Quincy', NULL, 'AZ', null union all
select 3, 'J', 'Doe', NULL, 'Phoenix', 'AZ', 'USA'


select
          a.REC
         ,case
            when nullif(a.FIRSTName, 'UNK') is not null then a.FIRSTName
            when nullif(b.FIRSTName, 'UNK') is not null then b.FIRSTName
            when nullif(c.FIRSTName, 'UNK') is not null then c.FIRSTName
            else                                             a.FIRSTName
          end                       FirstName
         ,case
            when nullif(a.LASTName, 'UNK') is not null then a.LASTName
            when nullif(b.LASTName, 'UNK') is not null then b.LASTName
            when nullif(c.LASTName, 'UNK') is not null then c.LASTName
            else                                            a.LASTName
          end                       LastName
         ,case
            when nullif(a.MIDDLE, 'UNK') is not null then a.MIDDLE
            when nullif(b.MIDDLE, 'UNK') is not null then b.MIDDLE
            when nullif(c.MIDDLE, 'UNK') is not null then c.MIDDLE
            else                                          a.MIDDLE
          end                       MIDDLE
         ,case
            when nullif(a.CITY, 'UNK') is not null then a.CITY
            when nullif(b.CITY, 'UNK') is not null then b.CITY
            when nullif(c.CITY, 'UNK') is not null then c.CITY
            else                                        a.CITY
          end                       CITY
         ,case
            when nullif(a.STATE, 'UNK') is not null then a.STATE
            when nullif(b.STATE, 'UNK') is not null then b.STATE
            when nullif(c.STATE, 'UNK') is not null then c.STATE
            else                                         a.STATE
          end                       STATE
         ,case
            when nullif(a.CTRY, 'UNK') is not null then a.CTRY
            when nullif(b.CTRY, 'UNK') is not null then b.CTRY
            when nullif(c.CTRY, 'UNK') is not null then c.CTRY
            else                                        a.CTRY
          end                       CTRY
     from #Something    a
         ,#Something    b
         ,#Something    c
    where a.REC = 1
      and b.REC = 2
      and c.REC = 3

2 个答案:

答案 0 :(得分:0)

您似乎有几个缺少的业务规则,但这里的示例至少应该指向正确的方向。

create table #Something
(
    REC int
    , FIRSTName varchar(10)
    , LASTName varchar(10)
    , MIDDLE varchar(10)
    , CITY varchar(10)
    , STATE varchar(10)
    , CTRY varchar(10)
)

insert #Something
select 1, 'John', 'Doe', NULL, 'Phoenix', 'UNK', null union all
select 2, 'John', 'Doe', 'Quincy', NULL, 'AZ', null union all
select 3, 'J', 'Doe', NULL, 'Phoenix', 'AZ', 'USA'

select 1
    , MAX(nullif(FIRSTName, 'UNK')) as FirstName
    , MAX(nullif(LASTName, 'UNK')) as LastName
    , MAX(nullif(MIDDLE, 'UNK')) as Middle
    , MAX(nullif(CITY, 'UNK')) as City
    , MAX(nullif(STATE, 'UNK')) as [State]
    , MAX(nullif(CTRY, 'UNK')) as Country
from #Something

答案 1 :(得分:0)

让你开始的东西。

声明

@x varchar(2)='1' ,@ sql varchar(max)

而@x< (从#Something中选择max(REC)

开始 在@.REC = x'+ @x +'上设置@sql = isnull(@sql,'')+'left join #Something x'+ @x +'。REC - '+ @x

设置@x = @x +1 端

设置@sql ='select * from #Something a'+ @sql +',其中a.REC = 1'

exec(@sql)