我有一个相当宽的表,其中包含数据稀疏。当我查询它时,我倾向于获得许多空的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的角度来看,我确实认为将数据显示留给视图是有意义的,但认为它在带宽方面效率不高。或许以这种方式做这件事并不值得讨论。
答案 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
*/