【发布时间】:2016-07-16 05:16:16
【问题描述】:
在 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,则从下一行中选择值,如果为空,则下一行,等所有选定的行。 奖励如果我不仅可以覆盖 NULLS,而且 value = 'UNK' 将是我的下一步。理想情况下,上述内容的组合记录应如下所示:
REC FIRST LAST MIDDLE CITY STATE CTRY
1 John Doe Quincy Phoenix AZ USA
我玩弄了 EXCEPT 和各种 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
【问题讨论】:
-
你怎么知道这都是同一个人?我可以看到在大多数情况下使用 MAX,但你没有任何东西可以表明什么组成了一个组。如果你有 Jane Doe 会怎样?为什么她是约翰而不是简?也许是您发布的示例过于简化。
-
用户决定使用哪些记录进行合并。如果表有 Jane Doe,则用户没有选择 Jane。用户选择了记录 1、2 和 3(方便)。我不一定需要潜在匹配的逻辑,而是在缩小潜在匹配范围后该怎么做。
-
好的。那么你怎么知道应该是 John 而不是 J?
-
用户再次确定这一点。他们选择一个主行 - 在示例中为第 1 行。仅当值为 NULL(或 UNK)时,脚本才需要考虑查看后续行。
-
那么你需要澄清更多的事情。什么定义了后续? Rec 专栏?为什么中间名最终是“昆西”?它在任何行上都不是 NULL 或 UNK,所以它不应该是一个空字符串吗?还是您想要每列的最大值?
标签: sql sql-server unions except