根据字段名称列选择
Posted
技术标签:
【中文标题】根据字段名称列选择【英文标题】:Select based on column of field names 【发布时间】:2021-08-19 12:54:15 【问题描述】:我希望能够合并多个表,以便对用户在我的数据库中的所有表中所做的事情有一个共同的了解。我所有的表都有“终端”和“创建日期”作为公共字段。
这样做的最终目标是在不实际使用 PIVOT 或 UNPIVOT 的情况下旋转表并将它们合并,因为我不想在我的 SQL 中手动调用每个表中的每个列。我虽然关于使用 sys.columns 和 sys.tables 以某种方式动态地从表中选择所有字段,但似乎无法将我的大脑包裹在它周围。所以架构将如下所示。
Table | DateTime | Field | Data |
---|---|---|---|
userhistory | 12/31/2020 11:35:16 PM | logonoff | on |
event | 1/1/2021 12:00:00 AM | emergencyType | Fire |
event | 1/1/2021 12:00:00 AM | createDate | 1/1/2021 12:00:00 AM |
event | 1/1/2021 12:00:00 AM | respondingAgency | FD |
unithistory | 1/1/2021 12:01:30 AM | respondingUnit | FireTruck1 |
unithistory | 1/1/2021 12:01:30 AM | createDate | 1/1/2021 12:01:30 AM |
unithistory | 1/1/2021 12:01:30 AM | unitStatus | Dispatched |
unithistory | 1/1/2021 12:02:30 AM | respondingUnit | FireTruck1 |
unithistory | 1/1/2021 12:02:30 AM | createDate | 1/1/2021 12:02:30 AM |
unithistory | 1/1/2021 12:02:30 AM | unitStatus | Canceled |
event | 1/1/2021 12:02:35 PM | closeDate | 1/1/2021 12:02:35 PM |
userhistory | 1/1/2021 12:02:36 PM | logonoff | off |
我创建了一个存储过程,允许我查看表名和日期时间。我所有的表都有一个日期时间字段,但字段数量不同。这里是 SP:
CREATE PROCEDURE [dbo].[TerminalHistoryTimeline]
@Terminal varchar(100),
@StartDate datetime2(0),
@EndDate datetime2(0)
AS
BEGIN
SET NOCOUNT ON;
select 'tableA' TableName, createDate from tableA where terminal = @Terminal and createDate between @StartDate2 and @EndDate2
union all
select 'tableB' TableName, createDate from tableB where terminal = @Terminal and createDate between @StartDate2 and @EndDate2
union all
select 'tableC' TableName, createDate from tableC where terminal = @Terminal and createDate between @StartDate2 and @EndDate2
option(recompile)
END
我想我不确定如何将“字段”和“数据”列添加到此 SP
【问题讨论】:
你给我们的数据集是预期的结果还是样本数据?另一个是什么样的? 这是预期的结果 “对方长什么样?” 【参考方案1】:Row—>for json—>openjson()=unpivot(或 xml 代替 json)..fiddle.. [也可以使用 values() 代替 union]。
select top(5) 'x' as terminal, dateadd(second, checksum(newid())%10000, getdate()) as _date, *
into t1
from sys.all_objects;
select top(2) 'x' as terminal, dateadd(second, checksum(newid())%10000, getdate()) as _date, *
into t2
from sys.all_columns;
select 't1' /*<--!*/ as tbl, _date, o.[key] as colname, o.value as colvalue
from t1 /*<--!*/ as t
cross apply openjson((select t.* for json path,without_array_wrapper)) as o
where terminal = 'X'
and o.[key] not in ('_date','terminal')
union all
select 't2' /*<--!*/ as tbl, _date, o.[key] as colname, o.value as colvalue
from t2 /*<--!*/ as t
cross apply openjson((select t.* for json path,without_array_wrapper)) as o
where terminal = 'X'
and o.[key] not in ('_date','terminal');
【讨论】:
以上是关于根据字段名称列选择的主要内容,如果未能解决你的问题,请参考以下文章