it-swarm-ko.tech

SQL : NULL 값만있는 열 선택

모든 행에 대해 NULL 값만 포함하는 테이블의 모든 열을 어떻게 선택합니까? MS SQL Server 2005을 사용하고 있습니다. 테이블에서 사용되지 않는 열을 찾아서 삭제할 수 있습니다.

46
Bryan Roth

다음은 SQL 2005 이상 버전입니다. ADDR_Address를 테이블 이름으로 바꾸십시오.

declare @col varchar(255), @cmd varchar(max)

DECLARE getinfo cursor for
SELECT c.name FROM sys.tables t JOIN sys.columns c ON t.Object_ID = c.Object_ID
WHERE t.Name = 'ADDR_Address'

OPEN getinfo

FETCH NEXT FROM getinfo into @col

WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @cmd = 'IF NOT EXISTS (SELECT top 1 * FROM ADDR_Address WHERE [' + @col + '] IS NOT NULL) BEGIN print ''' + @col + ''' end'
    EXEC(@cmd)

    FETCH NEXT FROM getinfo into @col
END

CLOSE getinfo
DEALLOCATE getinfo
66
Charles Graham
SELECT cols
FROM table
WHERE cols IS NULL
21
Eight Characters

NULL 값만있는 "Person"테이블의 모든 열 목록이 표시됩니다. 결과는 비어 있거나 단일 열의 이름이 포함 된 여러 결과 집합으로 표시됩니다. 다른 테이블과 함께 사용하려면 "개인"을 두 곳에서 바꿔야합니다.

DECLARE crs CURSOR LOCAL FAST_FORWARD FOR SELECT name FROM syscolumns WHERE id=OBJECT_ID('Person')
OPEN crs
DECLARE @name sysname
FETCH NEXT FROM crs INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC('SELECT ''' + @name + ''' WHERE NOT EXISTS (SELECT * FROM Person WHERE ' + @name + ' IS NOT NULL)')
    FETCH NEXT FROM crs INTO @name
END
CLOSE crs
DEALLOCATE crs
5
MobyDX

다음은 2008 년 이후 Bryan의 업데이트 된 버전입니다. INFORMATION_SCHEMA.COLUMNS를 사용하고 테이블 스키마 및 테이블 이름에 변수를 추가합니다. 열 데이터 유형이 출력에 추가되었습니다. 열 데이터 형식을 포함하면 특정 데이터 형식의 열을 찾을 때 도움이됩니다. 열 너비 또는 기타를 추가하지 않았습니다.

출력을 위해 RAISERROR ... WITH NOWAIT가 사용되므로 PRINT처럼 마지막에 텍스트가 한 번에 (대부분) 즉시 표시됩니다.

SET NOCOUNT ON;

DECLARE
 @ColumnName sysname
,@DataType nvarchar(128)
,@cmd nvarchar(max)
,@TableSchema nvarchar(128) = 'dbo'
,@TableName sysname = 'TableName';

DECLARE getinfo CURSOR FOR
SELECT
     c.COLUMN_NAME
    ,c.DATA_TYPE
FROM
    INFORMATION_SCHEMA.COLUMNS AS c
WHERE
    c.TABLE_SCHEMA = @TableSchema
    AND c.TABLE_NAME = @TableName;

OPEN getinfo;

FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @cmd = N'IF NOT EXISTS (SELECT * FROM ' + @TableSchema + N'.' + @TableName + N' WHERE [' + @ColumnName + N'] IS NOT NULL) RAISERROR(''' + @ColumnName + N' (' + @DataType + N')'', 0, 0) WITH NOWAIT;';
    EXECUTE (@cmd);

    FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
END;

CLOSE getinfo;
DEALLOCATE getinfo;
4
user2466387

아니면 열에 NULL 값만 있는지 여부를 확인하고 싶습니까?

질문에 대한 추가 설명이 도움이 될 수 있습니다.

EDIT : Ok .. 여기에 당신을 갈 수있는 정말 거친 코드가 있습니다 ...

SET NOCOUNT ON
DECLARE @TableName Varchar(100)
SET @TableName='YourTableName'
CREATE TABLE #NullColumns (ColumnName Varchar(100), OnlyNulls BIT)
INSERT INTO #NullColumns (ColumnName, OnlyNulls) SELECT c.name, 0 FROM syscolumns c INNER JOIN sysobjects o ON c.id = o.id AND o.name = @TableName AND o.xtype = 'U'
DECLARE @DynamicSQL AS Nvarchar(2000)
DECLARE @ColumnName Varchar(100)
DECLARE @RC INT
    SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0
    WHILE @@ROWCOUNT > 0
    BEGIN
        SET @RC=0
        SET @DynamicSQL = 'SELECT TOP 1 1 As HasNonNulls FROM ' + @TableName + ' (nolock) WHERE ''' + @ColumnName + ''' IS NOT NULL'
        EXEC sp_executesql @DynamicSQL
        set @[email protected]@rowcount
        IF @RC=1
        BEGIN
            SET @DynamicSQL = 'UPDATE #NullColumns SET OnlyNulls=1 WHERE ColumnName=''' + @ColumnName + ''''
            EXEC sp_executesql @DynamicSQL
        END
        ELSE
        BEGIN
            SET @DynamicSQL = 'DELETE FROM #NullColumns WHERE ColumnName=''' + @ColumnName+ ''''
            EXEC sp_executesql @DynamicSQL
        END
    SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0
    END

SELECT * FROM #NullColumns

DROP TABLE #NullColumns
SET NOCOUNT OFF

예, 더 쉬운 방법이 있지만 지금 바로 회의가 있습니다. 행운을 빕니다!

4
Kevin Fairchild

넌 할 수있어:

select 
  count(<columnName>)
from
  <tableName>

개수가 0을 반환하면 해당 열의 모든 행이 모두 NULL이거나 테이블에 행이 전혀 없음을 의미합니다.

로 변경할 수 있습니다

select 
    case(count(<columnName>)) when 0 then 'Nulls Only' else 'Some Values' end
from 
    <tableName>

자동화하려는 경우 시스템 테이블을 사용하여 원하는 테이블의 열 이름을 반복 할 수 있습니다.

2
kristof

실제로 2005 년에 대해서는 확실하지 않지만 2008 년은 그것을 먹었습니다.

USE [DATABASE_NAME] -- !
GO

DECLARE @SQL NVARCHAR(MAX)
DECLARE @TableName VARCHAR(255)

SET @TableName = 'TABLE_NAME'   -- !

SELECT @SQL = 
(
    SELECT 
        CHAR(10)
        +'DELETE FROM ['+t1.TABLE_CATALOG+'].['+t1.TABLE_SCHEMA+'].['+t1.TABLE_NAME+'] WHERE '
        +(
            SELECT  
            CASE t2.ORDINAL_POSITION 
                WHEN (SELECT MIN(t3.ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS t3 WHERE t3.TABLE_NAME=t2.TABLE_NAME) THEN ''
                ELSE  'AND '
            END
            +'['+COLUMN_NAME+'] IS NULL' AS 'data()'
            FROM INFORMATION_SCHEMA.COLUMNS t2 WHERE t2.TABLE_NAME=t1.TABLE_NAME FOR XML PATH('')
         )  AS 'data()'
    FROM INFORMATION_SCHEMA.TABLES t1 WHERE t1.TABLE_NAME = @TableName FOR XML PATH('')
)

SELECT @SQL -- EXEC(@SQL)
1
user8120267

또한 NULL뿐만 아니라 모두 동일한 값을 갖는 필드를 검색하는 것이 좋습니다.

즉, 각 테이블의 각 열에 대해 쿼리를 수행하십시오.

SELECT COUNT(DISTINCT field) FROM tableName

결과적으로 1을 반환하는 것에 집중하십시오.

1
squadette

모든 열 값이 NULL 인 모든 행을 나열해야하는 경우 COLLATE 함수를 사용합니다. 값 목록을 가져 와서 null이 아닌 첫 번째 값을 반환합니다. 모든 열 이름을 목록에 추가하면 IS NULL, 널만 포함하는 모든 행을 가져와야합니다.

SELECT * FROM MyTable WHERE COLLATE(Col1, Col2, Col3, Col4......) IS NULL

실제로 columns null이있는 테이블은 없어야합니다. 이는 primary key (null 일 수 없음). 기본 키가없는 것은 피해야합니다. 이것은 첫 번째 정상적인 형태를 s습니다.

1
The Doc
SELECT  t.column_name
FROM    user_tab_columns t
WHERE   t.nullable = 'Y' AND t.table_name = 'table name here' AND t.num_distinct = 0;
0
user3827049

Null을 허용하지 않는 열을 테스트하는 데 쓸모가 없기 때문에 성능을 향상시킬 수있는 작은 테스트가 추가 된 'user2466387'버전의 업데이트 된 버전 :

AND IS_NULLABLE = 'YES'

전체 코드 :

SET NOCOUNT ON;

DECLARE
 @ColumnName sysname
,@DataType nvarchar(128)
,@cmd nvarchar(max)
,@TableSchema nvarchar(128) = 'dbo'
,@TableName sysname = 'TableName';

DECLARE getinfo CURSOR FOR
SELECT
     c.COLUMN_NAME
    ,c.DATA_TYPE
FROM
    INFORMATION_SCHEMA.COLUMNS AS c
WHERE
    c.TABLE_SCHEMA = @TableSchema
    AND c.TABLE_NAME = @TableName
    AND IS_NULLABLE = 'YES';

OPEN getinfo;

FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @cmd = N'IF NOT EXISTS (SELECT * FROM ' + @TableSchema + N'.' + @TableName + N' WHERE [' + @ColumnName + N'] IS NOT NULL) RAISERROR(''' + @ColumnName + N' (' + @DataType + N')'', 0, 0) WITH NOWAIT;';
    EXECUTE (@cmd);

    FETCH NEXT FROM getinfo INTO @ColumnName, @DataType;
END;

CLOSE getinfo;
DEALLOCATE getinfo;
0
Sylvain Bruyere

이 시도 -

DECLARE @table VARCHAR(100) = 'dbo.table'

DECLARE @sql NVARCHAR(MAX) = ''

SELECT @sql = @sql + 'IF NOT EXISTS(SELECT 1 FROM ' + @table + ' WHERE ' + c.name + ' IS NOT NULL) PRINT ''' + c.name + ''''
FROM sys.objects o
JOIN sys.columns c ON o.[object_id] = c.[object_id]
WHERE o.[type] = 'U'
    AND o.[object_id] = OBJECT_ID(@table)
    AND c.is_nullable = 1

EXEC(@sql)
0
Jasmina Shevchenko

열 집합을 반복하고 각 열을 확인해야합니다. DESCRIBE 테이블 명령으로 모든 열 목록을 얻을 수 있어야합니다.

의사 코드 :


foreach $column ($cols) {
   query("SELECT count(*) FROM table WHERE $column IS NOT NULL")
   if($result is zero)  {
      # $column contains only null values"
      Push @onlyNullColumns, $column;
   } else {
      # $column contains non-null values
   }
}
return @onlyNullColumns;

나는 이것이 약간의 직관적이지 않은 것처럼 보이지만 SQL은 열을 선택하는 기본 방법을 제공하지 않으며 행만 선택합니다.

0
Daniel Papasian