sql server查询包含更改历史记录的维度

zfciruhq  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(208)

我在sql server中有一个维度表,它以以下格式存储具有更改历史记录的值:

[Position_History]
Position          Person    Inserted     Deleted
Sales 1           Mark      2019-01-01   2019-02-01
Sales 2           Mark      2019-02-01   2019-05-01
Sales 3           Mark      2019-05-01   2020-07-01
Senior Developer  Peter     2019-01-01   2020-07-01
Junior Developer  John      2019-01-01   2019-04-01
Project Manager   John      2019-04-01   2020-07-01

插入=记录插入日期。
删除=更新记录的日期。
查询特定日期的职位状态时,只需简单的where查询即可:

SELECT Position, Person FROM Position_History WHERE Inserted <= '2019-05-01' AND Deleted > '2019-05-01'

With result:

Position          Person
Sales 3           Mark 
Senior Developer  Peter
Project Manager   John

但是,我不知道使用哪种方法来创建一个查询,该查询将返回日期列表的结果。例如,我想知道连续3个月的状态-“2019-03-01”,“2019-04-01”,“2019-05-01”
我想要的结果是:

Position          Person  Date
Sales 2           Mark    2019-03-01
Senior Developer  Peter   2019-03-01
Junior Developer  John    2019-03-01
Sales 2           Mark    2019-04-01
Senior Developer  Peter   2019-04-01
Project Manager   John    2019-04-01
Sales 3           Mark    2019-05-01
Senior Developer  Peter   2019-05-01
Project Manager   John    2019-05-01

我正在寻找一种方法,可以动态地接受参数作为参数列表或表,避免硬编码x查询的联合。
谢谢你的帮助!

pgky5nke

pgky5nke1#

如果我正确理解了您的请求,那么您的问题不在于查询的逻辑,而在于如何对多个日期运行该逻辑。在这种情况下,您可以将所需的日期放入一个表中并与之联接:

create table #dates(ReportingDate date);
insert #dates 
values ('2019-03-01'),
       ('2019-04-01'),
       ('2019-05-01');

select ph.Position, ph.Person, dt.ReportingDate
from   dbo.Position_History ph
join   #dates               dt on ph.Inserted <= dt.ReportingDate
                                  and ph.Deleted > dt.ReportingDate

如果您希望能够从应用程序中传入,可以使用表值参数以及函数或存储过程。例如:

create type dbo.ReportingDates as table(ReportingDate date);
create function dbo.PositionsAtDates(@dates dbo.ReportingDates readonly) 
returns table as return
(
   select ph.Position, ph.Person, dt.ReportingDate
   from   dbo.Position_History ph
   join   @dates               dt on ph.Inserted <= dt.ReportingDate
                                     and ph.Deleted > dt.ReportingDate
);

-- usage within SSMS:
declare @d dbo.ReportingDates;
insert @d values ('2020-06-01'), ('2020-07-01');
select * from dbo.PositionsAtDates(@d);

如果你想从一个c应用程序中使用它,你需要用 SqlDbType = SqlDbType.Structured ,可以将其值设置为 DataTable . 请参阅此线程或此ms文档
有关在sql中传递“数组”的其他方法,请参阅erland sommarskog指南

t98cgbkg

t98cgbkg2#

我能想到的一个可能的方法是,
小提琴-https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=e4d980ca238769feef5bbb49c451a23d
我将日期值硬编码以供演示,但实际上您可以将这些值保存在单独的表中。您也可以替换 between 带的子句 >= AND < 操作员适当地包括/排除记录。
示例sql-

select mt.position, mt.person, dt.filter_date from (SELECT '2019-03-01'  as filter_date
UNION
SELECT '2019-04-01'
UNION 
Select '2019-05-01') dt
Join
(SELECT Position, Person, inserted, deleted FROM Position_History) mt
ON dt.filter_date between mt.inserted and mt.deleted;

如下图所示,适当地替换between子句-

mt.inserted <= dt.filter_date and mt.deleted > dt.filter_date

相关问题