如何在SQL中从查询中过滤空列?

时间:2011-07-29 17:49:18

标签: sql filter

我有一个相当宽的表,其中包含数据稀疏。当我查询它时,我倾向于获得许多空的VARCHAR列。

A | B | C | D | E | F | G | H | I | J | K | L | 
  | x |   |   | x | x |   | x |   |   |   |   | 
  |   |   |   | x | x |   |   |   |   |   | x | 
  |   |   |   |   | x |   |   |   |   |   |   | 
  | x |   |   | x | x |   |   |   |   |   | x | 
  |   |   |   | x | x |   |   |   | x |   |   | 
  |   | x |   | x |   |   |   |   | x |   | x | 
  | x |   |   | x | x |   | x |   | x |   | x | 

如何从结果集中过滤掉空列?我找不到似乎适用的SQL关键字。

B | C | E | F | H | J | L | 
x |   | x | x | x |   |   | 
  |   | x | x |   |   | x | 
  |   |   | x |   |   |   | 
x |   | x | x |   |   | x | 
  |   | x | x |   | x |   | 
  | x | x |   |   | x | x | 
x |   | x | x | x | x | x |

编辑:这是出于显示目的,我不打算用结果集中的数据修改表。从MVC的角度来看,我确实认为将数据显示留给视图是有意义的,但认为它在带宽方面效率不高。或许以这种方式做这件事并不值得讨论。

2 个答案:

答案 0 :(得分:3)

这是......非常奇怪的要求。你在使用select *吗?到目前为止,解决这个问题的最简单方法就是只说出你想要的列,然后你才能找到它们。

为什么您甚至想要随机删除列,具体取决于您尝试选择的值范围?如果您的计划/报告/任何期望特定列存在(即使null)并且它被静默删除,因为该范围始终为null会怎样?

答案 1 :(得分:0)

好的,所以这是一个有点复杂的动态SQL生成集,它将为您提供所需的内容。如果要使用它,必须将其粘贴到存储过程中。

FilterColTest是我用于测试的测试表。我将在查询中保留定义等,以便您可以对表/列进行适当的调整。

/*
create table FilterColTest (
    a int, b int, c int, d int, e int, f int, g int, h int, i int, j int)
insert into FilterColTest
select null,1,null,null,1,0,null,1,null,null
union select null,null,null,null,0,0,null,null,null,null
union select null,1,null,null,1,0,null,1,null,1
union select null,1,null,null,1,1,null,1,null,null
union select 1,1,0,null,1,0,null,1,null,null

--select * from FilterColTest
go
*/

declare @ColumnList table (ID int identity, colName varchar(max))

insert into @ColumnList(colName)
select column_name 
from information_schema.columns
where table_name = 'FilterColTest'

declare 
    @id int, @maxid int, @count int,
    @cols varchar(max), @sql nvarchar(max)

select @id = 1, @maxid = max(ID)
from @ColumnList

while @id <= @maxid
begin
    select @sql = 'select @count = count(*) from FilterColTest where ' + 
            colName + ' is not null'
    from @ColumnList
    where ID = @id 

    exec sp_executesql @sql, N'@count int output', @count output

    select @cols = isnull(@cols + ', ' + colName, colName)
    from @ColumnList
    where ID = @id and @count > 0

    set @id = @id + 1
end

select @sql = 'select ' + @cols + ' from FilterColTest'
exec sp_executesql @sql
go

/*
drop table FilterColTest
go
*/