根据字段名称列选择

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');

【讨论】:

以上是关于根据字段名称列选择的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - 根据用户的选择选择列'名称'列'id'和'parent'中的行彼此相等

如何根据字段名称公司名称隐藏列名称公司名称的数据?

数据库设计基础步骤

ZF2中获取mysql表字段名

根据从仪表板提示中的选择对分析列进行排序

Java 根据bean字段名获取bean属性的名称