【问题标题】:How to filter empty columns from query in SQL?如何从 SQL 中的查询中过滤空列?
【发布时间】:2011-10-16 03:49:56
【问题描述】:

我有一张相当宽的表格,里面的数据很少。当我查询它时,我往往会得到很多空的 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 的角度来看,将数据的显示留给视图是有意义的,但认为它在带宽方面效率不高。也许这不是一个值得这样做的理由。

【问题讨论】:

  • 我假设您在查询之前不知道哪些列会为空,对吧?
  • 为什么您的样本中没有删除 A 和 I?
  • 没有关键字可以做到这一点。您可以使用动态 SQL,但它会占用一些资源。如果您愿意,我可以发布一个外观示例
  • 你能解释一下你为什么要这样做吗?我希望有一种更简单的方法可以获得您正在寻找的结果。
  • @Daniel - 睡眠不足! :) 现在修复它。

标签: sql filter


【解决方案1】:

这是一个……非常奇怪的要求。你在用select *吗?到目前为止,解决这个问题的最简单方法就是说出您确实想要哪些列,而您只会得到这些列。

为什么您甚至希望根据您尝试选择的值的范围随机地有消失的列?如果您的程序/报告/任何内容都期望存在特定列(即使 null)并且由于该范围始终为 null 而被静默删除,该怎么办?

【讨论】:

  • 如果可以的话,我会投票很多次。这是一件非常奇怪的事情。
  • 嗯,这纯粹是为了显示目的,我不打算用结果集中的数据修改表。我确实认为从 MVC 的角度来看,将数据的显示留给视图是有意义的,但认为它在带宽方面效率不高。
  • 即使出于显示目的,这也很奇怪,您随机隐藏最终用户期望的列
【解决方案2】:

好的,所以这是一组有点复杂的动态 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
*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 2020-03-02
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多