Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从表中查找缺少的值_Sql_Sql Server_Loops_Recursion_Group By - Fatal编程技术网

Sql 如何从表中查找缺少的值

Sql 如何从表中查找缺少的值,sql,sql-server,loops,recursion,group-by,Sql,Sql Server,Loops,Recursion,Group By,我正试图简化一个更复杂的业务场景-请容忍我 我目前有一个类似下面的表格 它显示了一个人,他们正在进行的测试类型,视力测试,打字测试,测试开始的年份,测试结束的年份,以及完成测试的条目TestYear 我需要做的是找到从开始到结束的所有年份,一个人没有测试年。例如: 在处理了这个问题之后,我已经能够使它只在一个名称/测试类型下工作,但是当我试图在具有许多不同名称和测试类型的整个表中运行它时,我遇到了困难 下面创建了我当前拥有的表变量 理想情况下,我希望避免任何类型的循环,但就目前而言,任何关于如何

我正试图简化一个更复杂的业务场景-请容忍我

我目前有一个类似下面的表格

它显示了一个人,他们正在进行的测试类型,视力测试,打字测试,测试开始的年份,测试结束的年份,以及完成测试的条目TestYear

我需要做的是找到从开始到结束的所有年份,一个人没有测试年。例如:

在处理了这个问题之后,我已经能够使它只在一个名称/测试类型下工作,但是当我试图在具有许多不同名称和测试类型的整个表中运行它时,我遇到了困难

下面创建了我当前拥有的表变量

理想情况下,我希望避免任何类型的循环,但就目前而言,任何关于如何实现这一点的建议或反馈都将非常感谢

DECLARE @Tests Table (Name varchar(200), testType varchar(200), StartYear int, EndYear int, CurrentYear int)

INSERT INTO @Tests (Name ,testType, StartYear, EndYear, CurrentYear)
values ('John', 'Eye',  2016,   2021,   2018)
,('John',   'Eye',  2016,   2021,   2019)
,('Barry',  'Typing',   2019,   2021,   2019)
,('John',   'Typing',   2019,   2021,   2019)
,('John',   'Typing',   2019,   2021,   2020)

select * from @Tests

生成所有可能的年份,然后删除存在的年份:

with years as (
      select distinct name, testtype, startyear as currentyear, endyear
      from tests t
      union all
      select name, testtype, currentyear + 1, endyear
      from years
      where currentyear < endyear
     )
select y.*
from years y left join
     tests t
     on t.name = y.name and t.testtype = y.testtype and
        t.currentyear = y.currentyear
where t.name is null;
我怀疑你是否有超过100年的时间来完成一个名字/测试。但如果这样做,则需要选项maxrecursion 0


是一个dbfiddle。

此查询中有一些错误。它还将在输出中生成同一行的多个副本,其中用户在名称/测试类型对中有多个测试,但缺少测试。@Nick。我明白你的意思。谢谢你们的评论。非常感谢你们的投入。我将把这个问题转移到我更大的问题上,看看这是否能解决问题。我真的很感激你的建议:-太好了,很有魅力。非常感谢你。