Sql 选择仅包含值的列

Sql 选择仅包含值的列,sql,sql-server,sql-server-2008,tsql,dynamic-sql,Sql,Sql Server,Sql Server 2008,Tsql,Dynamic Sql,我在数据库中有一个表,结构如下 col1 col2 col3 col4 col5 col6 frnkeyid1 frnkeyid2 ----------------------------------------------------------- a 2 3 2 4 b 1 4 2 5 c 12

我在数据库中有一个表,结构如下

col1  col2  col3  col4 col5  col6  frnkeyid1  frnkeyid2
-----------------------------------------------------------
  a     2    3                         2          4
  b     1    4                         2          5 
  c     12   5                         2          6 
在上表中,
col4
col5
col6
中未插入任何数据。 现在我想编写一个过程/查询,从结果表中删除没有为该列输入值的所有列

F.e.上表的结果:

col1  col2  col3 frnkeyid1  frnkeyid2
-----------------------------------------
  a     2    3      2          4
  b     1    4      2          5 
  c     12   5      2          6 

如何执行此操作?

此解决方案从结果表中删除所有列

您需要使用动态SQL。让我举个例子

我猜,
no data
意味着
NULL

CREATE TABLE dbo.test (
    col1  char(1),
    col2  int,
    col3  int,
    col4  int,
    col5  int,
    col6  int,
    frnkeyid1 int,  
    frnkeyid2 int
)

INSERT INTO dbo.test  VALUES
('a', 2,  3, NULL, NULL, NULL, 2, 4),
('b', 1,  4, NULL, NULL, NULL, 2, 5),
('c', 12, 5, NULL, NULL, NULL, 2, 6)
这是一个测试表的声明。要生成查询并执行它,请使用以下代码:

DECLARE @TableName sysname = N'test',
        @SQLQuery nvarchar(max) = N''

SELECT @SQLQuery = @SQLQuery + N'
IF (
SELECT CASE WHEN COUNT(DISTINCT '+ QUOTENAME(c.[name]) +') = 0 AND MAX(' + QUOTENAME(c.[name]) +') IS NULL THEN 1 ELSE 0 END
FROM ' + QUOTENAME(s.[Name]) + '.' + QUOTENAME(t.[Name]) + ') = 1
BEGIN
    ALTER TABLE ' + QUOTENAME(s.[Name]) + '.' + QUOTENAME(@TableName) + '
    DROP COLUMN '+ QUOTENAME(c.[name]) +'

    PRINT ''Column name '+ QUOTENAME(c.[name]) + ' was droped from table ' + QUOTENAME(s.[Name]) + '.' + QUOTENAME(@TableName) + '''
END;'
FROM sys.tables t
INNER JOIN sys.columns c
    ON t.[object_id] = c.[object_id]
INNER JOIN sys.schemas s
    On t.[schema_id] = s.[schema_id]
WHERE t.[name] = @TableName

PRINT @SQLQuery
--EXEC (@SQLQuery)
打印报表会给你这个

IF (
SELECT CASE WHEN COUNT(DISTINCT [col1]) = 0 AND MAX([col1]) IS NULL THEN 1 ELSE 0 END
FROM [dbo].[test]) = 1
BEGIN
    ALTER TABLE [dbo].[test]
    DROP COLUMN [col1]

    PRINT 'Column name [col1] was droped from table [dbo].[test]'
END;
对于每列

所以,如果没有值,列将被删除。你可以删除

ALTER TABLE dbo.[test]
DROP COLUMN [col1]
并运行脚本查看将从表中删除哪些列

如果在测试表上运行此脚本,然后执行以下操作:

SELECT *
FROM dbo.test
这将为您带来:

col1    col2    col3    frnkeyid1   frnkeyid2
a       2       3       2           4
b       1       4       2           5
c       12      5       2           6
你可以试试这个

-- For obtain used columns
DECLARE @ColNames NVARCHAR(MAX) =''
SELECT  @ColNames = @ColNames + ', ' + QUOTENAME(ColNames) 
FROM MyTable UNPIVOT( V FOR ColNames IN ([col1],[col2],[col3],[col4],[col5],[col6],[frnkeyid1],[frnkeyid2])) UNPVT
GROUP BY QUOTENAME(ColNames)


DECLARE @query NVARCHAR(MAX) = 'SELECT ' + STUFF(@ColNames,1,1,'') + ' FROM MyTable'

EXEC (@query)
结果:

col1        col2        col3        frnkeyid1   frnkeyid2
----------- ----------- ----------- ----------- -----------
1           2           3           2           4
2           1           4           2           5
3           12          5           2           6

您使用哪种RDBMS?我删除了所有这些dbms标记。将其中一个放回原处,即此处实际使用的dbms。sql server 2008