使用大多数填充列过滤SELECT语句

时间:2009-07-14 15:05:40

标签: sql-server tsql

我有一个声明,从具有两个值索引的表中选择不同的行

SELECT distinct Reference, Value1, Value2, Value3, Value4 FROM [tblHistory]

其中Reference是另一个字段“Project”的索引。对于特定系统,只使用Reference作为索引将此数据插入到另一个表中,因为Value1到Value4应该对于相同的Reference始终相同 - 但是大约1/500则不是。

如果在一个或多个Value1-Value4字段中存在重复的Reference AND差异,我需要选择具有最完整的Value1-Value4字段的行,因为它们通常为NULL。如果所有实例具有相同数量的填充列,则可以返回找到的第一行。

除了使用临时表和代码

之外
case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 end
as CountOfNulls

有没有办法过滤数据,所以我只获得填充最多的行?

我正在运行MS SQL Server 2000。

4 个答案:

答案 0 :(得分:1)

您可以查看Coalesce函数,但老实说我可能会像上面那样使用Case语句。

你不想使用它的原因是什么?

根据评论,该表不仅仅是4个值字段。但是担心的是,保留最高空值的临时表是必要的。

我觉得可能在视图中实现的Case解决方案仍然是一个可行且良好的解决方案。

答案 1 :(得分:1)

这只是一种预感,因为我还没有看到你的数据库,但看起来这是一个实际应该是两个的表。正如我所说,这可能是出于性能或其他合理原因而做的,但是你需要报告它的方式表明这个表应该分开。

尽管如此,如果我没有其他选择,我会创建一个列,其中包含该行的填充列数,并在更新特定记录时以编程方式更新它。

答案 2 :(得分:1)


-- count() will not include NULL, so we can avoid making complex conditions
;
with
sum_cnt
(
    Reference,
    cnt
)
as
(
    select 
        Reference, 
        count(Value1) + count(Value2) + count(Value3) + count(Value4) 
    from 
        tblHistory 
    group by 
        Reference
)
select top 1
    Reference
from
    sum_cnt 
order by
    cnt desc


答案 3 :(得分:0)

这不是一个很好的方法,但是我把这个代码放在一起并且它有效:

SELECT distinct Reference, Value1, Value2, Value3, Value4

FROM [tblHistory]
WHERE Reference+cast(4-(case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 END) AS varchar) IN (

SELECT myref + CAST(MAX(CountOfNonNulls) AS VARCHAR) FROM
(

SELECT myref, 4-(case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 end)
as CountOfNonNulls

FROM [tblHistory]
)l
GROUP BY Reference
)

我实际上没有这个表结构,所以我没有测试它,但它似乎工作。想法是通过将最高的CountOfNonNull添加到Reference字段并使用它来限制选择来创建一个“新”键 - 这意味着讨厌的CASE代码运行两次但我拥有的其他过滤器(未显示)将人口限制为在我的系统中大约有80行,所以我可以忍受这个。

如果有两行具有相同的CountOfNonNulls值但不同的Value1-Value4字段,我还没有看到它会做什么 - 我认为它会破坏。在这种情况下,我可能会将Value1-Value4字段添加到我的“新”键中,但这有点傻。

非常感谢任何改进建议!