get a count of each value from every column in a table SQL Server

前端 未结 3 1873
庸人自扰
庸人自扰 2021-01-14 20:20

So I looked this up and this question is very similar but it\'s missing a key piece: SQL Server count number of distinct values in each column of a table

So in that

相关标签:
3条回答
  • 2021-01-14 20:41

    You could use:

    DECLARE @Table SYSNAME = 'TableName'; 
    DECLARE @SQL NVARCHAR(MAX) = ''
    SELECT @SQL = STUFF((SELECT ' UNION SELECT ''' + name 
                                + ''' AS [Column], ' 
                                + 'CAST(' + QUOTENAME(Name)
                                + ' AS NVARCHAR(MAX)) AS [ColumnValue], COUNT(*) AS [Count] FROM ' 
                                + QUOTENAME(@Table) + ' GROUP BY ' + QUOTENAME(Name)
                        FROM   sys.columns 
                        WHERE  object_id = Object_id(@Table)
                        -- concatenate result strings with FOR XML PATH
                        FOR XML PATH ('')), 1, 7, '');
    
    EXECUTE sp_executesql @SQL;
    

    Which will produce SQL Like the following for a table with two columns (Column1 and Column2)

    SELECT 'Column1' AS [Column], 
            CAST([Column1] AS NVARCHAR(MAX)) AS [ColumnValue], 
            COUNT(*) AS [Count] 
    FROM    [TableName] 
    GROUP BY [Column1] 
    UNION 
    SELECT  'Column2' AS [Column], 
            CAST([Column2] AS NVARCHAR(MAX)) AS [ColumnValue], 
            COUNT(*) AS [Count] 
    FROM    [TableName] 
    GROUP BY [Column2]
    

    EDIT

    If you want a new result set for each column then use:

    DECLARE @Table SYSNAME = 'TableName'; 
    DECLARE @SQL NVARCHAR(MAX) = '';
    SELECT @SQL = (SELECT ' SELECT ' + QUOTENAME(Name) 
                            + ', COUNT(*) AS [Count] FROM ' 
                            + QUOTENAME(@Table) + ' GROUP BY ' + QUOTENAME(Name) + ';'
                    FROM   sys.columns 
                    WHERE  object_id = Object_id(@Table)
                    -- concatenate result strings with FOR XML PATH
                    FOR XML PATH (''));
    
    EXECUTE sp_executesql @SQL;
    

    Which would produce SQL Like:

    SELECT  [Column1], 
            COUNT(*) AS [Count] 
    FROM    [callsupplier] 
    GROUP BY [Column1];
    
    SELECT  [Column2], 
            COUNT(*) AS [Count] 
    FROM    [callsupplier] 
    GROUP BY [Column2];
    
    0 讨论(0)
  • 2021-01-14 20:41

    thought i would take a stab at this whilst waiting for a backup to restore

    hope this does what you require

    create Table #Temp 
    (tableName varchar(100),
    columnName varchar(100),
    value varchar(1000),
    distinctItems int)
    
    Declare @tabName as varchar(100)
    Declare @colName as varchar(100)
    Declare @tabid as int
    
    Declare cursorTables Cursor
    for 
    select t.object_id , t.name , c.name from sys.tables t inner join sys.columns c on     t.object_id = c.object_id
    
    open cursorTables 
    Fetch Next from cursorTables into 
    @tabid,@tabName,@colName
    
    
    while @@Fetch_Status = 0 
    Begin
    
    declare @query as nVarchar(1000)
    set @query  = 'Insert into #Temp SELECT    ''' + @tabName + '''  , '''+ @colName +''', '     + @colName + ',  COUNT([' + @colName +']) AS Expr1 FROM          [' + @tabName+ '] group by     [' + @colName + ']'
    print @query
    exec sp_executesql @query
    
    Fetch Next from cursorTables into 
    @tabid,@tabName,@colName
    
    
    End 
    
    Close cursorTables
    Deallocate cursorTables
    
    select * from #temp
    
    drop table #temp
    

    produces some not very useful results on PK values and i suspect it would not work on columns greater than varchar(1000) but works on a fe of my dbs

    0 讨论(0)
  • 2021-01-14 21:01

    This version makes a good snippet:

    DECLARE @sql NVARCHAR(MAX) = N'';
    
    SELECT @sql += 'SELECT ''' + t.name + ''', ''' + c.name + ''', ' + c.name + ', COUNT(' + c.name + ') AS C FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' GROUP BY ' + c.name + ';' + CHAR(13)
        FROM sys.tables AS t
        INNER join sys.columns c on t.object_id = c.object_id
        INNER JOIN sys.schemas AS s ON t.[schema_id] = s.[schema_id] 
        WHERE s.name LIKE 'stage' AND t.name LIKE 'table' AND c.name LIKE '%whatever%';
    
    --PRINT @sql;
    EXEC sp_executesql @sql
    
    0 讨论(0)
提交回复
热议问题