选择至少具有一个非零值的行

问题描述 投票:0回答:3

我有一个包含 20 多列的表,有些行的所有列都只有 0。有没有办法过滤掉所有列都是0的行?

我可以用

select * 
from table 
where concat(col1, col2, col3) != '000'

但我不想在我的例子中写入 20 个以上的零,并且列数将来可能会增加。

我也可以用

select * 
from table 
where coalesce(col1, col2, col3) > 0 
   or coalesce(col1, col2, col3) < 0 

因为某些值可能是负数。但我不想写20+列名。

有没有动态的方法来解决这个问题?

sql sql-server
3个回答
0
投票

您可以使用 INFORMATION_SCHEMA 动态抓取表中的列。

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.columns 
WHERE TABLE_SCHEMA = "your_database" 
  AND TABLE_NAME = "your_table"

0
投票

使用根据 sys.tables 和 sys.colums 信息构造的动态 SQL。使用 ABS 对列求和,然后与零进行比较。

如果使用 2017 年之前的 SQL SERVER:

DECLARE @Criteria Varchar(max) =''
DECLARE @SQL NVarchar(max) =''

SELECT @Criteria=STUFF
( 
  (SELECT '+' + 'ABS('+ QUOTENAME(c.name) +')'
   FROM  sys.tables t
   JOIN sys.columns c  ON t.object_id = c.object_id
   WHERE t.name = 'Example'
   FOR XML PATH ('')
  ), 1, 1, ''
)  
    
--SELECT @Criteria returns ABS([A])+ABS([B])+ABS([C])

SET @SQL='SELECT * FROM Example WHERE ' +  @Criteria + ' !=0'

--SELECT @SQL Returns SELECT * FROM Example WHERE ABS([A])+ABS([B])+ABS([C]) !=0
 
EXEC sys.sp_executesql @SQL

如果 SQL Server 2017+:

DECLARE @Criteria Varchar(max) =''
DECLARE @SQL NVarchar(max) =''

SELECT @Criteria=STRING_AGG('ABS('+ QUOTENAME(c.name) +')','+')
FROM  sys.tables t
JOIN sys.columns c
  ON t.object_id = c.object_id
WHERE t.name = 'Example'
  
SET @SQL='SELECT * FROM Example WHERE ' +  @Criteria + ' !=0'
    
EXEC sys.sp_executesql @SQL

小提琴


0
投票

JSON方法(FOR JSON)可以将表行作为集合处理。之后,您可以解剖组件并检查是否满足条件。

参见示例。

测试源数据

create table test (id int,col1 int,col2 int,col3 int);
insert into test values
 (1,10,11,12)
,(2,20,21,22)
,(3,0,0,0)
,(4,30,0,33)
;
id col1 col2 col3
1 10 11 12
2 20 21 22
3 0 0 0
4 30 0 33

目标查询。我们在查询中不使用列名称,除了

id
列。

select *
  ,case when replace(replace(
    json_modify( 
        (SELECT * FROM test t2 where t2.id=t.id FOR JSON PATH,WITHOUT_ARRAY_WRAPPER )
            ,'$.id',null)
      ,'":0,"','":null,"'),'":0}','":null}') like '%:[0-9]%' 
   then 1 
   else 0 end fl
from test t
;

和输出

id col1 col2 col3 fl
1 10 11 12 1
2 20 21 22 1
3 0 0 0 0
4 30 0 33 1

一步一步相同的查询

select *
  ,case when jv3 like '%:[0-9]%' then 1 else 0 end fl
from(
  select *
    ,replace(replace(jv2,'":0,"','":null,"'),'":0}','":null}') jv3
  from(
    select *
     ,json_modify(jv,'$.id',null)jv2
    from(
       select id
         ,(SELECT * FROM test t2 where t2.id=t.id 
           FOR JSON PATH,WITHOUT_ARRAY_WRAPPER ) jv
       from test t
     )a
   )b
)c;
id jv jv2 jv3 fl
1 {"id":1,"col1":10,"col2":11,"col3":12} {"col1":10,"col2":11,"col3":12} {"col1":10,"col2":11,"col3":12} 1
2 {"id":2,"col1":20,"col2":21,"col3":22} {“col1”:20,“col2”:21,“col3”:22} {“col1”:20,“col2”:21,“col3”:22} 1
3 {"id":3,"col1":0,"col2":0,"col3":0} {"col1":0,"col2":0,"col3":0} {"col1":null,"col2":null,"col3":null} 0
4 {"id":4,"col1":30,"col2":0,"col3":33} {"col1":30,"col2":0,"col3":33} {"col1":30,"col2":null,"col3":33} 1

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.