Sql server 用于查找表中所有列的缺失值计数的动态SQL查询

Sql server 用于查找表中所有列的缺失值计数的动态SQL查询,sql-server,Sql Server,我想编写一个动态sql查询,以找出表中每列缺少值的计数。该表由40列组成,每列的写缺失计数很长,所以我们可以动态地进行吗?我试图按照下面提供的方式编写动态查询,但出现了如下错误: 必须声明标量变量“@sql” 查询: Declare @sql nvarchar(max) Declare @columnlist nvarchar(max) Declare @FieldName nvarchar(max) set @columnlist = 'Column 1,Column2 ,

我想编写一个动态sql查询,以找出表中每列缺少值的计数。该表由40列组成,每列的写缺失计数很长,所以我们可以动态地进行吗?我试图按照下面提供的方式编写动态查询,但出现了如下错误:

必须声明标量变量“@sql”

查询:

Declare @sql nvarchar(max)  
Declare @columnlist nvarchar(max)   
Declare @FieldName nvarchar(max)    

set @columnlist = 'Column 1,Column2 ,Column3 ,Column4 ,Column5 ,Column6 ,Column7 ,Column8 ,Column9 ,Column10 ,Column11 ,Column12,Column13'  

set @FieldName = 'Column 1,Column2 ,Column3 ,Column4 ,Column5 ,Column6 ,Column7 ,Column8 ,Column9 ,Column10 ,Column11 ,Column12,Column13'

set @sql = 'SELECT COUNT(*)-COUNT(' + @columnlist + ') as '+ @FieldName +'from table_name' 

exec (@sql)
试试这个

IF OBJECT_ID('TempDb..#MissingList') IS NOT NULL
    DROP TABLE #MissingList

CREATE TABLE #MissingList
(
    SeqNo INT IDENTITY(1,1),
    TABLE_NAME VARCHAR(255),
    COLUMN_NAME VARCHAR(255),
    MissingCount INT DEFAULT(0)
)

DECLARE @SQL NVARCHAR(MAX)

SELECT
    @SQL = REPLACE(REPLACE(L.List,'&#x0D',''),';','')
    FROM
    (
        SELECT 
            '
            INSERT INTO #MissingList(TABLE_NAME,COLUMN_NAME,MissingCount)
            SELECT TABLE_NAME = ''['+LTRIM(RTRIM(TABLE_SCHEMA))+'].['+LTRIM(RTRIM(TABLE_NAME))+']'',COLUMN_NAME = '''+LTRIM(RTRIM(COLUMN_NAME))+''',MissingCount = COUNT(1) - COUNT(['+LTRIM(RTRIM(COLUMN_NAME))+'])
            FROM ['+LTRIM(RTRIM(TABLE_SCHEMA))+'].['+LTRIM(RTRIM(TABLE_NAME))+']' AS [text()]
            FROM INFORMATION_SCHEMA.COLUMNS
            FOR XML PATH('')
    )L(LIST)

EXEC(@SQL)

SELECT
    *
    FROM #MissingList
试试这个:

DECLARE @sql nvarchar(max) = N'SELECT';
DECLARE @table_name nvarchar(256) = N'YourTableName'

SELECT @sql = @sql + ' COUNT(*)-COUNT(' + QUOTENAME(COLUMN_NAME) + ') as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
  AND TABLE_NAME = @table_name

SET @sql = LEFT(@sql, LEN(@sql) - 1) + ' from ' + @table_name

EXEC (@sql)
已添加

好的,下面是一个示例,说明如何使用相似的东西来计算每列中至少有一个重复的值的数量:

DECLARE @sql nvarchar(max) = N'WITH duplicates AS (SELECT';
DECLARE @table_name nvarchar(256) = N'YourTableName';

SELECT @sql = @sql 
  + N' CASE WHEN COUNT(' + QUOTENAME(COLUMN_NAME) 
  + N') OVER (PARTITION BY ' + QUOTENAME(COLUMN_NAME) 
  + N') > 1 THEN ' + QUOTENAME(COLUMN_NAME)  
  + N' END as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
  AND TABLE_NAME = @table_name;

SET @sql = LEFT(@sql, LEN(@sql) - 1) + ' from ' + @table_name + ') SELECT';

SELECT @sql = @sql 
  + N' COUNT(DISTINCT ' + QUOTENAME(COLUMN_NAME) 
  + N') as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
  AND TABLE_NAME = @table_name;

SET @sql = LEFT(@sql, LEN(@sql) - 1) + ' from duplicates';

EXEC (@sql);
您可以看到,它使用了2条SELECT语句,第一条语句创建了一个CTE,将所有没有重复项的值替换为NULL:

CASE WHEN COUNT([C1]) OVER (PARTITION BY [C1]) > 1 THEN [C1] END as [C1]

第二个使用COUNT DISTINCT来计算剩余的数量。这样做,值NULL将不被计算

你打错了。第二个查询
set@FieldName
中没有起始单引号。请尝试使用
“双引号”
使用
选择查询
@NisargShah我已经更新了它,但仍然得到相同的eError您更新了什么?我认为写下来(使用“复制和粘贴”)这40个表达式将比两次写下字段列表,然后生成将列列表字符串转换为某种表表达式的代码来动态生成表达式列表更快。使用
'
[`+@Variable+']]`不会停止注入,也不会处理名称不正确的对象(相信我,
QUOTENAME
是一个更好的选择。
QUOTENAME
的良好使用总是值得称赞的!但是,你确实在最后忘记了它,从“+@table\u name(如果
@table_name
是一个输入参数,那么这可能是最重要的地方)。@Larnu谢谢!老实说,我没有忘记,我故意把它漏掉了,因为表名可能是唯一“已知的”但你是对的,如果作为参数传递,它完全有意义。:-@WolfgangKais,与此类似,如果我需要使用动态查询查找每列重复数据的计数。怎么做?有可能吗?。。我试着使用上面提供的样本,但没有效果。我对每一列使用Group By,这不是一个正确的解决方案。下面是一个执行打印命令时显示的语法示例…示例选择[C1],COUNT([C1])作为[id]从表_name Group By[C1]的计数([C1])>1[C2],COUNT([C2])作为[C2]从表_name Group By[C2]的计数([C2])>1。。。。请建议一些解决方案。@Promila上面的查询只创建一行。“重复计数”是否也应产生一行?如果是这样的话,那么C1列的“重复编号”20对您意味着什么?它可能意味着一个值包含20倍或10个值,每个值有一个副本(或介于两者之间的任何值)。还是希望看到1或10(至少有一个重复的值的数目)?我建议先弄清楚一列计算的一些“规范”。然后,我们可以找出在一个查询中对多个列执行相同操作是否有意义。@WolfgangKais我需要对一列的每个值进行重复数据计数。我不确定一次查询是否可行。。