我有两个SQL表。
一个包含文件信息,如Table1
第二个包含打印记录表2
**Table1**
File_name TotalPages
====================
A 50
B 75
C 50
**Table2**
File_name from_page to_page
============================
A 13 15
A 21 30
B 13 13
A 41 41
要求是在用户选择文件时显示文件中待处理页面的范围。
例如:
当用户想要查看file_name A
的待处理记录时,用户应该看到下表中的表3File_name from_page to_page
===========================
A 1 12
A 16 20
A 30 40
A 42 50
我阅读了下面的SQL Gaps和Island,但无法找到方法。
答案 0 :(得分:0)
要执行此操作,您必须创建一个参考表,其中包含从1到最大页数的数字到您的文件中。并更新此表以实现您的结果。下面是示例代码 -
create table Table1 (File_name char(1) ,TotalPages int)
insert into Table1
select 'A' , 50
union
select 'B',75
union
select 'C',50
create table Table2 (File_name char(1) ,from_page int , to_page int )
insert into Table2
select 'A' , 13,15
union
select 'A',21,30
union
select 'B',13,13
union
select 'A',41,41
go
if exists ( select OBJECT_ID('tempdb.dbo.#Ref'))
begin
drop table #Ref
end
create table #Ref(i int , IsValue int , FileName char(1))
declare @File_name char(1) , @TotalPages int , @pagecount int
set @File_name = 'A' -------------<<< set your file name
select @TotalPages = TotalPages , @pagecount = 1 from Table1
while (@pagecount <= @TotalPages)
begin
insert into #Ref(i ,FileName)
select @pagecount , @File_name
set @pagecount = @pagecount+ 1
end
--select * from #Ref
go
update #Ref
set IsValue = 1
where i in (select i from #Ref cross join Table2
where i >=from_page and i <= to_page) ---- update the pages which are available
declare @File_name char(1) , @TotalPages int , @pagecount int , @isVal int = 2
select @TotalPages = TotalPages , @pagecount = 1 from Table1
while (@pagecount <= @TotalPages)
begin
if exists( select * from #Ref where i = @pagecount and IsValue is not null)
begin
set @isVal = @isVal + 1
end
update #Ref
set IsValue = @isVal
where i = @pagecount
and IsValue is null
set @pagecount = @pagecount + 1
end
select FileName ,MIN(i)from_page , MAX(i) to_page from #Ref
where IsValue <>1
group by FileName ,IsValue
答案 1 :(得分:0)
此查询需要SQL 2012或更高版本。如果版本较低,请使用row_number
订购@Table2
并加入下一行。
declare @Table1 table (
File_name char(1)
, TotalPages int
)
declare @Table2 table (
File_name char(1)
, from_page int
, to_page int
)
insert into @Table1
values
('A', 50)
,('B', 75)
,('C', 50)
insert into @Table2
values
('A', 13, 15)
,('A', 21, 30)
,('B', 13, 13)
,('A', 41, 41)
select
File_name, from_page = to_page + 1
, to_page = next_row - iif(TotalPages = next_row, 0, 1)
from (
select
a.*, b.TotalPages
, next_row = isnull(lead(a.from_page) over (partition by a.File_name order by a.from_page), b.TotalPages)
from
@Table2 a
join @Table1 b on a.File_name = b.File_name
) t
where
next_row - to_page > 1
union all
select
File_name, 1, min(from_page) - 1
from
@Table2
group by File_name
having min(from_page) > 1
order by 1, 2
输出:
File_name from_page to_page
---------------------------------
A 1 12
A 16 20
A 31 40
A 42 50
B 1 12
B 14 75
编辑: 这样的事情应该有效:
;with cte as (
select
*, rn = row_number() over (partition by File_name order by from_page)
from
@Table2
)
select
File_name, from_page = to_page + 1
, to_page = next_row - iif(TotalPages = next_row, 0, 1)
from (
select
a.*, c.TotalPages
, next_row = isnull(b.from_page, c.TotalPages)
from
cte a
left join cte b on a.File_name = b.File_name and a.rn + 1 = b.rn
join @Table1 c on a.File_name = c.File_name
) t
where
next_row - to_page > 1
union all
select
File_name, 1, min(from_page) - 1
from
@Table2
group by File_name
having min(from_page) > 1
order by 1, 2