动态 SQL 列选择

Dynamic SQL Column Selection

我目前有一个 table 充满了多天的数据。 这些日期被设置为数据 table 中的列,因此我需要反转 table 以执行相关查询。

select 所有以 2020%

开头的列的最简单方法是什么

我使用了以下问答 Selecting all columns that start with XXX using a wildcard? 为了创建一个单独的 Table 包含我需要的所有列

SELECT [COLUMN_NAME]
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [TABLE_NAME] = 'Table_Name'
AND [COLUMN_NAME] LIKE '2020%'
GO

但是不确定如何使用这个辅助 table 来简化我原来的问题。

您可以对已选择的列使用动态 unpivot。以下示例查询可能对您有所帮助。

DECLARE 
  @sql  NVARCHAR(MAX) = N'',
  @cols NVARCHAR(MAX) = N'';

SELECT @cols += ', ' + QUOTENAME(name)
  FROM sys.columns
  WHERE [object_id] = OBJECT_ID('yourtable')
  AND name LIKE '2020%';

SET @cols =  STUFF(@cols, 1, 1, '')

SELECT @sql = N'SELECT Other_columns, date_columns, val
  FROM 
  (
    SELECT Other_columns, '  + @cols + '
    FROM yourtable
  ) t
  UNPIVOT
  (
    val FOR date_columns IN (' + @cols + ')
  ) up;';
PRINT @sql;
-- EXEC sp_executesql @sql;

请找出最终的分贝<>fiddle here.

尽管我和 Zohar 不明白为什么每天都有一个 table 列...

对于MySQL

请考虑此 fiddle 中的解决方案:https://www.db-fiddle.com/f/7nxjo6hGRsX3Hn8GNqXBuC/0

create table dummy(
  id int,
  --
  relevant_data_01 varchar(255),
  relevant_data_02 varchar(255),
  --
  `20200101` int,
  `20200102` int,
  `20200103` int
);

insert into dummy values(1, 'a', 'b', 1, 2, 3);

select
  concat(
    '
      select *
      from (
    ',
      group_concat(
        concat('
          select
            id, relevant_data_01, relevant_data_02,
            ''', column_name, ''' as date_key,
            `', column_name, '`   as date_value
          from dummy')
        separator
          '
          union all
          '
      ),
    '
      ) d'
  )
into @sql
from INFORMATION_SCHEMA.columns
where
    table_name = 'dummy'
and column_name like '2020%';

PREPARE stmt FROM @sql;
EXECUTE stmt;

对于SQL服务器

编辑解决方案,我为 SQL 服务器提供了另一个 fiddle:http://sqlfiddle.com/#!18/f7874c/14

create table dummy(
  id int,
  --
  relevant_data_01 varchar(255),
  relevant_data_02 varchar(255),
  --
  [20200101] int,
  [20200102] int,
  [20200103] int
)

insert into dummy values(1, 'a', 'b', 1, 2, 3)

declare @sql nvarchar(max) = ''

select
  @sql =
    @sql +
    case
      when @sql = '' then ''
                     else char(13) + char(10) + 'union all' + char(13) + char(10)
    end + '
      select
        id, relevant_data_01, relevant_data_02,
        ''' + col.name + ''' as date_key,
        [' + col.name + ']   as date_value
      from dummy
    '
from
  sys.columns col
where
    col.object_id = OBJECT_ID('dummy')
and col.name like '2020%'
  
execute sp_executesql @sql