我在数据库中有几个表。我想找到哪些列(在哪些表中)没有任何值(列中的所有NULL)。我在下面的例子中,结果应该是
TestTable1 --> Var2
TestTable2 --> Variable1
我不知道如何创建这种查询。非常感谢您的帮助!
--create first table
create table dbo.TestTable1 (
sur_id int identity(1,1) not null primary key,
var1 int null,
var2 int null
)
go
--insert some values
insert into dbo.TestTable1 (var1)
select 1 union all select 2 union all select 3
--create second table
create table dbo.TestTable2 (
sur_id int identity(1,1) not null primary key,
variable1 int null,
variable2 int null
)
--and insert some values
insert into dbo.TestTable2 (variable2)
select 1 union all select 2 union all select 3
答案 0 :(得分:10)
对于单个列,count(ColumnName)
返回ColumName
不为空的行数:
select count(TheColumn)
from YourTable
您可以为所有列生成查询。根据Martin的建议,您可以使用is_nullable = 1
排除不能为null的列。例如:
select 'count(' + name + ') as ' + name + ', '
from sys.columns
where object_id = object_id('YourTable')
and is_nullable = 1
如果表的数量很大,您可以以类似的方式为所有表生成查询。所有表的列表都在sys.tables
。
答案 1 :(得分:4)
更新....好吧,我对这个
有太多乐趣了 Proc接受两个参数,即搜索表和&适用的标准。你可以将本质和where子句传递给第二个参数。我编写了proc来将双引号解释为单引号....再次,这是基于原始开发人员的概念。GO
/****** Object: StoredProcedure [dbo].[SearchAllTables] Script Date: 05/04/2011 14:29:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter PROC [dbo].[SearchAllTables2] ( @SEARCH_TABLE NVARCHAR(255), @CONDITION AS NVARCHAR(MAX) ) AS
BEGIN
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi -- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110), @COND_STR NVARCHAR(MAX)
SET @TableName = ''
--SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @CONDITION = REPLACE(@CONDITION,'"','''')
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE
TABLE_TYPE = 'BASE TABLE'
AND
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0 AND TABLE_NAME = @SEARCH_TABLE
) WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN SET @ColumnName = (
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND
TABLE_NAME = PARSENAME(@TableName, 1) AND QUOTENAME(COLUMN_NAME) > @ColumnName )
IF @ColumnName IS NOT NULL
BEGIN
SET @COND_STR = REPLACE(@CONDITION,'''','"')
INSERT INTO #Results
EXEC ( 'SELECT DISTINCT ''' + @TableName + '.' + @ColumnName + ''',''' + @COND_STR + ''' AS CONDITION FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' ' + @CONDITION)
PRINT ( 'SELECT DISTINCT ''' + @TableName + '.' + @ColumnName + ''',''' + @COND_STR + ''' AS CONDITION FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' ' + @CONDITION)
END
END
END
SELECT ColumnName, ColumnValue
FROM #Results
END
GO
-- to execute
exec [SearchAllTables2] 'TABLENAME','LIKE "%DOUG%"' -- double quotes are automatically escaped to single quotes...
根据以下版权修改的原始代码....仅使用部分。
GO
/****** Object: StoredProcedure [dbo].[SearchAllTables] Script Date: 05/04/2011 14:29:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter PROC [dbo].[SearchAllTables2] ( @TABLE_NAME NVARCHAR(255) ) AS
BEGIN
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi -- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
--SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE
TABLE_TYPE = 'BASE TABLE'
AND
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0 AND TABLE_NAME = @TABLE_NAME
) WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN SET @ColumnName = (
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND
TABLE_NAME = PARSENAME(@TableName, 1) AND QUOTENAME(COLUMN_NAME) > @ColumnName )
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC ( 'SELECT DISTINCT ''' + @TableName + '.' + @ColumnName + ''', ''IS NULL'' FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' IS NULL ')--LIKE ' + @SearchStr2 )
--PRINT ( 'SELECT DISTINCT ''' + @TableName + '.' + @ColumnName + ''', ''IS NOT NULL'' FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' IS NOT NULL ')--LIKE ' + @SearchStr2 )
END
END
END
SELECT ColumnName, ColumnValue
FROM #Results
END
GO
-- to execute
exec [SearchAllTables2] 'Master'
答案 2 :(得分:4)
这是我编写的用于执行相同操作的脚本,它是一个两步的手动过程:
SELECT 'SELECT COUNT( DISTINCT [' + COLUMN_NAME + ']) AS UniqueValues, ''' + TABLE_NAME + '.' + COLUMN_NAME + ''' AS ColumnName FROM [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] UNION ALL ' FROM INFORMATION_SCHEMA.COLUMNS ORDER BY TABLE_NAME, COLUMN_NAME
UNION ALL
语句。它看起来像这样:SELECT COUNT( DISTINCT [ModifiedByUserId]) AS UniqueValues, 'Inspections.ModifiedByUserId' AS ColumnName FROM [dbo].[Inspections] UNION ALL SELECT COUNT( DISTINCT [Notes]) AS UniqueValues, 'Inspections.Notes' AS ColumnName FROM [dbo].[Inspections] UNION ALL SELECT COUNT( DISTINCT [PublicPassword]) AS UniqueValues, 'Inspections.PublicPassword' AS ColumnName FROM [dbo].[Inspections] UNION ALL SELECT COUNT( DISTINCT [ShopId]) AS UniqueValues, 'Inspections.ShopId' AS ColumnName FROM [dbo].[Inspections] UNION ALL SELECT COUNT( DISTINCT [Status]) AS UniqueValues, 'Inspections.Status' AS ColumnName FROM [dbo].[Inspections] UNION ALL SELECT COUNT( DISTINCT [SupervisorUserId]) AS UniqueValues, 'Inspections.SupervisorUserId' AS ColumnName FROM [dbo].[Inspections] UNION ALL
答案 3 :(得分:2)
这非常有用,不会被放入一个方便的小系统proc中 - 特别是如果你刚刚继承了遗留数据库,并想知道你可以放弃或忽略哪些列。
/*
Show the count of not-null values in a table
*/
create proc sp_aaShowAllNullColumns @tableName varchar(255) as
begin
set nocount on
declare @sql nvarchar(4000)
declare @cols nvarchar(4000)
declare @tcols table( colbit nvarchar(255) )
insert @tcols
select 'count(' + name + ') as ' + name + ', ' as colbit
from sys.columns
where object_id = object_id(@tableName)
and is_nullable = 1
select @cols = coalesce( @cols, ', ', '' ) + colbit from @tcols
select @cols = substring( @cols, 1, (len(@cols) - 1) )
select @cols = isnull( @cols, '' )
select @sql = 'select count(*) as Rows' + @cols + ' from ' + @tableName
exec sp_executeSql @sql
end
go
exec sys.sp_MS_marksystemobject 'sp_aaShowAllNullColumns'
go
use Bookshop
go
exec sp_aaShowAllNullColumns 'Books'
go
答案 4 :(得分:1)
这是一个bash脚本,用于SQLite数据库中的所有非空表(或此类数据库中的所有指定表),标识all-NULL列。假定可以与SQLite数据库对话,则可以在您选择的编程语言中使用相同的技术。
#!/bin/bash
function help {
cat <<EOF
Syntax: $0 databasefile [table ...]
If no tables are specified, then for each non-empty user table in the
specified SQLite database row, this script will emit the column names
of those columns in which all the values are NULL. If any tables are
specified, only the specified tables are scanned.
The script is written to make it easy to modify the criteria and the output.
Thanks to SQL, two passes are required per table, and if no tables are
specified, an additional invocation of sqlite3 is required.
Column names are written in the form: tablename.columnname
Requirements:
sqlite3 on the \$PATH
Options:
-v | --verbose :: emit additional information
EOF
}
while [ "$1" ]
do case "$1" in
-h | --help | "" ) help
exit
;;
-v | --verbose ) VERBOSE=1
shift
;;
* ) break
;;
esac
done
function verbose { if [ "$VERBOSE" ] ; then echo "$@" >&2 ; fi ; }
db="$1"
shift
if [ ! -s "$db" ] ; then echo "$0 : $db not found" ; exit ; fi
# To prevent loading ~/.sqliterc specify -init ""
# Global: db
function nullcolumns {
local table="$1"
local count column field nulls
( read count
if [ -n "$count" ] ; then
verbose "Row count for $table: $count"
if [ "$count" -gt 0 ] ; then
while read column ; do
echo "SELECT '$column', * FROM
(SELECT COUNT(*) FROM $table WHERE '$column' IS NULL);"
done |
sqlite3 -readonly "$db" | while IFS="|" read field nulls ; do
verbose $table.$field ... $nulls
if [ "$nulls" -eq $count ] ; then echo "$table.$field" ; fi
done
else cat > /dev/null
fi
else cat > /dev/null
fi ) < <(sqlite3 -readonly "$db" "select count(*) from '$table';
select name from pragma_table_info( '$table' )")
}
if [ $# = 0 ] ; then
sqlite3 -readonly "$db" .tables | while read table ; do
nullcolumns "$table"
done
else
for table ; do
nullcolumns "$table"
done
fi