【问题标题】:Select column only with values仅选择具有值的列
【发布时间】:2023-03-24 02:56:01
【问题描述】:

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

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

上表中,col4col5col6中没有插入数据。 现在我想编写一个过程/查询,从结果表中删除没有为该列输入值的所有列。

F.e.上表的结果:

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

我该怎么做?

【问题讨论】:

标签: sql sql-server sql-server-2008 tsql dynamic-sql


【解决方案1】:

此解决方案从字面上删除结果表中的所有列

您需要使用动态 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)

PRINT 语句会给你这个

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]

然后运行脚本来查看,哪些列将从表中删除。

如果你在测试表上运行这个脚本然后make:

SELECT *
FROM dbo.test

这会给你带来:

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

【讨论】:

    【解决方案2】:

    你可以试试这个。

    -- 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-06
      • 2019-11-06
      • 2022-12-21
      • 2017-07-07
      • 2020-02-03
      • 2011-12-06
      相关资源
      最近更新 更多