Sql 是否基于前几个月提取不存在的值?

Sql 是否基于前几个月提取不存在的值?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有tb1 code Name sal_month ==== ===== ======== 101 john 02/2017 102 mathe 02/2017 103 yara 02/2017 104 sara 02/2017 101 john 03/2017 102 mathe 03/2017 103 yara 03/2017 104

我有tb1

code  Name        sal_month
====  =====       ========
101    john       02/2017
102    mathe      02/2017
103    yara       02/2017
104    sara       02/2017
101    john       03/2017
102    mathe      03/2017
103    yara       03/2017
104    sara       03/2017
101    john       04/2017
103    yara       04/2017
二月份,他们和三月份一样都拿到了薪水 如何基于前几个月提取不存在的值

结果应该是肯定的

code   sal_month
====   =======
102    04/2017
104    04/2017

提前感谢

首先,我创建了此表:

create table #T(code int, sal_month varchar(10))

insert into #T values(101,'2/2017'),(102,'2/2017'),(103,'2/2017'),(104,'2/2017'),
(101,'3/2017'),(102,'3/2017'),(104,'3/2017'),(101,'4/2017'),(103,'4/2017')
其次,我执行了这个查询:

SELECT code, Max(sal_Month)
From #T
Where code not in (select code from #T where  sal_Month = (select Max(sal_Month) from #T))
Group by code
然后我得到了以下结果:


注意:我使用的是SQL SERVER 2012

我认为您可以按id分组计算每月工资,类似这样,然后选择显示少于3次的行

select code, count (sal_month) from tb1
group by code
having count (sal_month) < 3
在这之后,您加入初始表只是为了过滤代码中需要的完整行

因此,最终的查询将类似于他的:

select code, sal_month
from tb1 a
join (select code, count (sal_month) from tb1
group by code
having code < 3) X on a.code = X.code
大概是这样的:

DECLARE @DataSource TABLE
(
    [code] INT
   ,[sal_month] VARCHAR(12)
);

INSERT @DataSource ([code], [sal_month])
VALUES (101, '2/2017')
      ,(102, '2/2017')
      ,(103, '2/2017')
      ,(104, '2/2017')
      ,(101, '3/2017')
      ,(102, '3/2017')
      ,(104, '3/2017')
      ,(101, '4/2017')
      ,(103, '4/2017');

WITH DataSource AS
(
    SELECT *
         ,DENSE_RANK() OVER (ORDER BY [sal_month]) AS [MonthID]
         ,MAX([sal_month]) OVER () AS [MaxMonth]
    FROM @DataSource DS1
)
SELECT DS1.[code]   
      ,DS1.[sal_month]
FROM DataSource DS1
LEFT JOIN DataSource DS2
    ON DS1.[code] = DS2.[code]
    AND DS1.[MonthID] = DS2.[MonthID] - 1
LEFT JOIN DataSource DS3
    ON DS1.[code] = DS3.[code]
    AND DS1.[MonthID] = DS3.[MonthID] + 1
WHERE DS2.[code] IS NULL
    AND DS3.[code] IS NOT NULL
    AND DS1.[sal_month] <> DS1.[MaxMonth];
这样我们就可以按字符串排序了

在核心部分,我使用行数和排序月份作为字符串

这样做的目的是寻找下个月不存在但上个月有记录的所有记录;同时,排除上个月的记录,因为他们不可能在下个月有记录

试试这个:

select tb2.code, tb2.sal_month from tb
right join (
select code, sal_month, datepart(month, sal_month) + 1 as next_sal_month from tb) as tb2
on (tb.code = tb2.code and datepart(month, tb.sal_month) = tb2.next_sal_month)
where tb2.next_sal_month < 5 and tb.sal_month is null
在结果集中还有一个额外的记录:代码103在3月份没有收到工资,但在2月份收到了,所以也包括在内


下面是一个尝试:

在没有关于表的更多事实的情况下,创建月份和代码的两个轴的笛卡尔乘积,然后左键连接存储的数据。然后,当与每种可能的组合进行比较时,当不存在存储数据时,很容易识别缺少的项

如果您确实使用了sal_month的主表和/或代码,您可能已经有了要使用的主表,但如果没有,您可以使用selectdistinct动态创建它们,如下所示


dbfiddle

这与?请,并学习如何创建。请解释您的输出,并添加您可能尝试过的任何内容谢谢您的快速响应,但如果您查看我的输出,代码102和104在2017年4月不存在,但存在101。我的查询输出与您相同recommended@ALDHEEB正如你在结果中看到的那样。仅显示102和104。它们在过去并不存在month@ALDHEEB我想你收到了很多有用的答案。您必须接受一个或回复它们。您已经测试过交叉连接方法了吗?使用这种方法,根据存储的数据评估每个可能的月和代码组合,然后轻松准确地识别任何缺失的数据。
select tb2.code, tb2.sal_month from tb
right join (
select code, sal_month, datepart(month, sal_month) + 1 as next_sal_month from tb) as tb2
on (tb.code = tb2.code and datepart(month, tb.sal_month) = tb2.next_sal_month)
where tb2.next_sal_month < 5 and tb.sal_month is null
create table tbl1 (code int, sal_month varchar(10))

insert into tbl1 values(101,'2/2017'),(102,'2/2017'),(103,'2/2017'),(104,'2/2017'),
(101,'3/2017'),(102,'3/2017'),(104,'3/2017'),(101,'4/2017'),(103,'4/2017')
select c.code, m.sal_month
from ( select distinct sal_month from tbl1 ) m
cross join ( select distinct code from tbl1 ) c
Left join tbl1 t on m.sal_month = t.sal_month and c.code = t.code
Where t.sal_month IS NULL
code | sal_month ---: | :-------- 103 | 3/2017 102 | 4/2017 104 | 4/2017