数据库:
我有2张桌子。 Table1
有50个字段,其中25个字段的名称类似于SomeValue1
,SomeValue2
... SomeValue25
。 Table2
类似,但范围从SomeOtherValue1
到SomeOtherValue30
。
1)对于这两个表格,这些表格编号为'列允许null
。
2)对于这两个表格,这些表格编号为'如果列之前的所有列都不是null
,则列应仅允许值。因此,如果SomeValue3
和SomeValue1
都不是SomeValue2
,您应该只能在null
中输入值。
问题:
我试图找到两个表中的所有记录,其中给定记录的n个字段超过null
个字段。
不幸的是,我无法信任数据的完整性。我根本无法做SELECT * FROM Table WHERE SomeValueN IS NOT NULL
,因为我无法保证上面的规则#2得到执行。
问题:
有没有办法可以像SELECT MyPrimaryKey FROM Table WHERE COUNT([all_columns with null values]) > n
那样手动输入每个列名?
答案 0 :(得分:0)
使用cross apply(values ())
进行动态展开,并汇总并添加having count()...
测试设置是一个包含25个可为空的列的表,以SomeValue
开头:
create table t (id int not null identity(1,1) , SomeValue1 int null , SomeValue2 int null , SomeValue3 int null , SomeValue4 int null , SomeValue5 int null , SomeValue6 int null , SomeValue7 int null , SomeValue8 int null , SomeValue9 int null , SomeValue10 int null , SomeValue11 int null , SomeValue12 int null , SomeValue13 int null , SomeValue14 int null , SomeValue15 int null , SomeValue16 int null , SomeValue17 int null , SomeValue18 int null , SomeValue19 int null , SomeValue20 int null , SomeValue21 int null , SomeValue22 int null , SomeValue23 int null , SomeValue24 int null , SomeValue25 int null )
insert into t values
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
,(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, null)
,(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, null, null)
,(4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, null, null, null)
,(5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, null, null, null, null)
,(6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, null, null, null, null, null)
,(7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, null, null, null, null, null, null)
,(8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, null, null, null, null, null, null, null)
,(9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, null, null, null, null, null, null, null, null)
,(10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, null, null, null, null, null, null, null, null, null)
,(11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, null, null, null, null, null, null, null, null, null, null)
,(12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, null, null, null, null, null, null, null, null, null, null, null)
,(13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, null, null, null, null, null, null, null, null, null, null, null, null)
,(14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(16, 16, 16, 16, 16, 16, 16, 16, 16, 16, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(17, 17, 17, 17, 17, 17, 17, 17, 17, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(18, 18, 18, 18, 18, 18, 18, 18, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(19, 19, 19, 19, 19, 19, 19, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(20, 20, 20, 20, 20, 20, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(21, 21, 21, 21, 21, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(22, 22, 22, 22, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(23, 23, 23, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(24, 24, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
,(25, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
查询:
declare @cols as nvarchar(max);
declare @sql as nvarchar(max);
set @cols = stuff((
select ',(''' + C.name + ''','+ quotename(C.name) +')'
from sys.columns c
where c.object_id = object_id('dbo.t') /* <-- table name */
and c.name like 'SomeValue%' /* <-- column name starts with */
order by c.column_id
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'');
set @sql = '
select t.id --, u.column_name, u.column_value
from t
cross apply (
values '+@cols+') u (column_name,column_value)
group by t.id
having count(u.column_value) > 10;' /* <-- how many not null */
select @sql as CodeGenerated;
exec sp_executesql @sql;
rextester演示:http://rextester.com/UKFM26061
代码生成:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+
| CodeGenerated | |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+
| | |
| select t.id --, u.column_name, u.column_value | |
| from t | |
| cross apply ( | |
| values ('SomeValue1',[SomeValue1]),('SomeValue2',[SomeValue2]),('SomeValue3',[SomeValue3]),('SomeValue4',[SomeValue4]),('SomeValue5',[SomeValue5]),('SomeValue6',[SomeValue6]),('SomeValue7',[SomeValue7]),('SomeValue8',[SomeValue8]),('SomeValue9',[SomeValue9]),('SomeValue10',[SomeValue10]),('SomeValue11',[SomeValue11]),('SomeValue12',[SomeValue12]),('SomeValue13',[SomeValue13]),('SomeValue14',[SomeValue14]),('SomeValue15',[SomeValue15]),('SomeValue16',[SomeValue16]),('SomeValue17',[SomeValue17]),('SomeValue18',[SomeValue18]),('SomeValue19',[SomeValue19]),('SomeValue20',[SomeValue20]),('SomeValue21',[SomeValue21]),('SomeValue22',[SomeValue22]),('SomeValue23',[SomeValue23]),('SomeValue24',[SomeValue24]),('SomeValue25',[SomeValue25])) u (column_name,column_value) | |
| group by t.id | |
| having count(u.column_value) > 10; | |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+
查询执行返回:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
+----+