我试图找到遗失或“跳过”'我表中的值。这是我的表的一个例子。
| Country | U | Date |
| USA | 1 | 1/1/2015 |
| USA | 2 | 2/1/2015 |
| USA | 3 | 3/1/2015 |
| USA | 5 | 5/1/2015 |
| USA | 6 | 6/1/2015 |
| USA | 7 | 7/1/2015 |
| USA | 8 | 8/1/2015 |
| USA | 9 | 9/1/2015 |
| Germany | 2 | 4/1/2015 |
| Germany | 3 | 5/1/2015 |
| Germany | 4 | 6/1/2015 |
| Germany | 5 | 7/1/2015 |
| Germany | 6 | 8/1/2015 |
| Germany | 7 | 9/1/2015 |
| Canada | 1 | 3/1/2015 |
| Canada | 2 | 4/1/2015 |
| Canada | 3 | 6/1/2015 |
| Canada | 4 | 7/1/2015 |
我需要找到一些可能导致两个不同查询的事情,这是好的。
首先按国家/地区分组并按美国过滤时,您会发现U列从1-9开始,但缺少U = 4以及与该行于2015年4月1日对应的月份。
其次,当按国家/地区分组并按德国过滤时,您会发现U列缺少第一条记录,其中U = 1且其对应日期为3/1/2015。
然后最后按国家/地区分组并按加拿大过滤时,您会发现U列具有顺序排序,但是Date列缺少一个月 - 2015年5月1日。
我已经尝试了LAG()
和LEAD()
方法,但这似乎不起作用,因为我无法汇总U
。有没有人解决这个问题?
答案 0 :(得分:0)
我认为您可以使用cte来构建数字和日期表,然后使用left join
主表来查找丢失的记录。
with nums as (select 1 as num union all select 2 union all ... select 9)
, dates as (select '01/01/2015' as dt union all select '02/01/2015'..
select '12/01/2015')
select n.num, t.country, d.dt
from nums n
left join tablename t on n.num = t.U
left join dates d on d.dt = t.date
where t.U is null or t.date is null
答案 1 :(得分:0)
您似乎只是想找到丢失的月份,U
可以忽略,除非它以大于1
的整数开头,在这种情况下您需要使用{{ 1}}查找U
在U
开始时存在的缺失日期。
如果您需要在1
中找到缺失的数字,则必须对其进行调整,因为它只关注缺少的日期。
鉴于数据:
U
您可以使用两个查询为每个国家/地区构建declare @data table (Country varchar(10), U int, [Date] date)
insert into @data values
('USA', 1, '1/1/2015'),
('USA', 2, '2/1/2015'),
('USA', 3, '3/1/2015'),
('USA', 5, '5/1/2015'),
('USA', 6, '6/1/2015'),
('USA', 7, '7/1/2015'),
('USA', 8, '8/1/2015'),
('USA', 9, '9/1/2015'),
('Germany', 2, '4/1/2015'),
('Germany', 3, '5/1/2015'),
('Germany', 4, '6/1/2015'),
('Germany', 5, '7/1/2015'),
('Germany', 6, '8/1/2015'),
('Germany', 7, '9/1/2015'),
('Canada', 1, '3/1/2015'),
('Canada', 2, '4/1/2015'),
('Canada', 3, '6/1/2015'),
('Canada', 4, '7/1/2015')
和min
日期列表,然后构建每个国家/地区应存在的完整日期列表。
max
如果我们检查select Country, dateadd(month, (-1 * min(U)) + 1, min([Date])) as min_Date, max([Date]) as max_Date
into #min_max
from @data
group by Country
;with cte (Country, [Date]) as (
select Country, min_Date from #min_max
union all
select cte.Country, dateadd(month, 1, cte.Date) from #min_max t inner join cte on t.Country = cte.Country where cte.[Date] < t.max_Date
)
select *
into #ranges
from cte
和#min_max
中的数据,您会看到以下内容:
#ranges
然后在select * from #min_max
Country min_Date max_Date
---------- ---------- ----------
Canada 2015-03-01 2015-07-01
Germany 2015-03-01 2015-09-01
USA 2015-01-01 2015-09-01
select * from #ranges order by 1, 2
Country Date
---------- ----------
Canada 2015-03-01
Canada 2015-04-01
Canada 2015-05-01
Canada 2015-06-01
Canada 2015-07-01
Germany 2015-03-01
Germany 2015-04-01
Germany 2015-05-01
Germany 2015-06-01
Germany 2015-07-01
Germany 2015-08-01
Germany 2015-09-01
USA 2015-01-01
USA 2015-02-01
USA 2015-03-01
USA 2015-04-01
USA 2015-05-01
USA 2015-06-01
USA 2015-07-01
USA 2015-08-01
USA 2015-09-01
中找到原始数据中不存在的记录很简单:
#ranges
然后我们放下临时表:
select *
from #ranges r
where not exists (
select 1
from @data d
where r.Country = d.Country
and r.[Date] = d.[Date]
)
Country Date
---------- ----------
Germany 2015-03-01
USA 2015-04-01
Canada 2015-05-01