Find the non null columns in SQL Server in a table

前端 未结 2 1930
清歌不尽
清歌不尽 2021-01-17 06:03

I have read many answers but they are all for PL/SQL or Oracle, I could not find anything for Microsoft SQL-Server.

My table :

CREATE TABLE StudentSc         


        
相关标签:
2条回答
  • 2021-01-17 06:38

    You could achieve it by issuing:

    SELECT 
      FORMATMESSAGE('SELECT col = ''%s.%s.%s'' FROM %s.%s HAVING COUNT(*) != COUNT(%s)', 
         QUOTENAME(TABLE_SCHEMA),
         QUOTENAME(TABLE_NAME),
         QUOTENAME(COLUMN_NAME),
         QUOTENAME(TABLE_SCHEMA),
         QUOTENAME(TABLE_NAME),
         QUOTENAME(COLUMN_NAME)
      )
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE IS_NULLABLE = 'YES';
    

    db<>fiddle demo

    It will generate script for checking individual column.

    HAVING COUNT(*) != COUNT(col_name) -- it means that column contains at least single NULL
    
    HAVING COUNT(col_name) = 0 AND COUNT(*) != 0 -- it means all values in columns are NULL
    

    This approach could be polished with using STRING_AGG to get single query per table and with dynamic SQL you could avoid the need of copying the query.

    EDIT:

    Fully baked-solution:

    DECLARE @sql NVARCHAR(MAX);
    
    SELECT @sql = STRING_AGG(
      FORMATMESSAGE('SELECT table_schema = ''%s''
                            ,table_name = ''%s''
                            ,table_col_name = ''%s'' 
                            ,row_num = COUNT(*)
                            ,row_num_non_nulls = COUNT(%s)
                            ,row_num_nulls = COUNT(*) - COUNT(%s)
                     FROM %s.%s', 
         QUOTENAME(TABLE_SCHEMA),
         QUOTENAME(TABLE_NAME),
         QUOTENAME(COLUMN_NAME),
         QUOTENAME(COLUMN_NAME),
         QUOTENAME(COLUMN_NAME),
         QUOTENAME(TABLE_SCHEMA),
         QUOTENAME(TABLE_NAME),
         QUOTENAME(COLUMN_NAME)), ' UNION ALL' + CHAR(13)
                   ) WITHIN GROUP(ORDER BY TABLE_SCHEMA, TABLE_NAME)
    
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE IS_NULLABLE = 'YES'
      AND TABLE_NAME = ?        -- filter by table name
      AND TABLE_SCHEMA = ?;     -- filter by schema name
    
    SELECT @sql;
    EXEC(@sql);
    

    db<>fiddle demo

    Output:

    +---------------+-----------------+------------------+----------+--------------------+---------------+
    | table_schema  |   table_name    | table_col_name   | row_num  | row_num_non_nulls  | row_num_nulls |
    +---------------+-----------------+------------------+----------+--------------------+---------------+
    | [dbo]         | [StudentScore]  | [Student_Name]   |       7  |                 6  |             1 |
    | [dbo]         | [StudentScore]  | [Student_Score]  |       7  |                 5  |             2 |
    +---------------+-----------------+------------------+----------+--------------------+---------------+    
    
    0 讨论(0)
  • 2021-01-17 06:50

    Perhaps you want to look at INFORMATION_SCHEMA.COLUMNS. The column IS_NULLABLE provides this information.

    Note that the INFORMATION_SCHEMA tables (well, they are really views) are Standard SQL, so this information is available in most database. Oracle has not (yet?) adopted them.

    0 讨论(0)
提交回复
热议问题