动态 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
我目前有一个 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