我有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
2月份,所有人都获得了3月份的工资 如何根据前几个月提取不存在的值?
结果应该来了
code sal_month
==== =======
102 04/2017
104 04/2017
提前感谢
答案 0 :(得分:1)
首先我创建了这个表:
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
答案 1 :(得分:0)
我认为你可以计算按id分组的salary_month,类似这样,并选择显示少于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
答案 2 :(得分:0)
这样的事情:
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];
一些注意事项:
我们需要一种方法对月份进行排序,因为你以非常不实用的方式存储它们并不容易;您没有使用日期/日期时间列,并且您的字符串不是有效日期;另外,你使用的字符串并不好,因为如果你有不同年份的[sal_month]
,我们将无法对它们进行排序;你应该考虑这个 - 一种选择是使用这种格式:
201512
201701
201702
201711
通过这种方式,我们可以按字符串排序。
我使用ROW_NUMBER
并将月份排序为字符串;
这个想法是寻找下个月没有的所有记录,但在前一个记录中有记录;同时,排除了上个月的记录,因为他们不可能在下个月有记录;
答案 3 :(得分:0)
试试这个:
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月份收到了薪水,因此它也包括在内。
在这里SQL fiddle,尝试:)
答案 4 :(得分:0)
如果没有关于您的牌桌的更多事实,请创建一个月份的2轴的笛卡儿积。代码,然后左边加入存储的数据。当与每种可能的组合相比时,没有存储数据时,很容易识别缺失的项目。
您可能已经拥有要使用的sal_month和/或代码的主表,如果您确实使用了这些表,但如果没有,您可以使用select distinct动态创建它们,如下所示。
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
dbfiddle here