Sql 是否基于前几个月提取不存在的值?
我有tb1Sql 是否基于前几个月提取不存在的值?,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
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