我有一些需要验证的数据,虽然我找到了一个在excel中运行的快速公式,但我想找到一些可以做同样的SQL,所以我可以在我的数据库中使用它作为支票现在和然后
数据就是这样:
ACACIA ST (KLN) | 1073 | 1149 | FAIL! | 76
ACACIA ST (KLN) | 1073 | 1151 | FAIL! | 78
ACACIA ST (KLN) | 1150 | 1332 | FAIL! | 182
ACACIA ST (KLN) | 1151 | 1332 | FAIL! | 181
ACACIA ST (KLN) | 1606 | 2079 | | 473
ACTIVITY ST (WRK) | 6 | 215 | WIN! | 209
ACTIVITY ST (WRK) | 215 | 227 | WIN! | 12
ACTIVITY ST (WRK) | 227 | 423 | WIN! | 196
ACTIVITY ST (WRK) | 423 | 549 | WIN! | 126
ACTIVITY ST (WRK) | 549 | 600 | | 51
ADRIENNE CT (WMN) | 5 | 107 | WIN! | 102
ADRIENNE CT (WMN) | 107 | 122 | | 15
AERODROME RD (LYB) | 0 | 140 | WIN! | 140
AERODROME RD (LYB) | 140 | 428 | WIN! | 288
AERODROME RD (LYB) | 428 | 716 | WIN! | 288
AERODROME RD (LYB) | 716 | 998 | WIN! | 282
AERODROME RD (LYB) | 998 | 1280 | WIN! | 282
AERODROME RD (LYB) | 1280 | 1566 | WIN! | 286
AERODROME RD (LYB) | 1566 | 1851 | WIN! | 285
AERODROME RD (LYB) | 1851 | 2136 | WIN! | 285
AERODROME RD (LYB) | 2136 | 2421 | | 285
那么有更多的数据,大约11000 +行。
现在的想法是每个路段(第一列)都有一个起始和结束链(第二和第三列)和一个长度(最后一列),结束链应该是下一个段的起始链,提供路段名称相同(当然按开始链式排序)。你可以看到,因为第一行结束链不等于下一个的开始失败。
我对伪代码的不良尝试:
If EndChainage != NextStartChainge Where RoadSegment = NextRoadSegment Error
我需要做的是选择不遵循末端链规则的所有路段=下一个的开始链接。
所以上表的结果是:
ACACIA ST (KLN) | 1073 | 1149 | FAIL! | 76
ACACIA ST (KLN) | 1073 | 1151 | FAIL! | 78
ACACIA ST (KLN) | 1150 | 1332 | FAIL! | 182
ACACIA ST (KLN) | 1151 | 1332 | FAIL! | 181
希望这是有道理的。我尝试了它,但似乎可以让它工作,我的SQL技能有点缺乏。
编辑:我可以同时使用SQL Server和PostgreSQL。
答案 0 :(得分:2)
我的第一次尝试很简单但是如果你的ACACIA ST情况正确,当正确的段不是正确的顺序时,它就不能正常运行。
select * from stackchallenge se
where not exists (select * from stackchallenge
where startchain = se.endchain and segment = se.segment)
and exists (select * from stackchallenge
where segment = se.segment and endchain > se.endchain)
第二项工作使用了一些SQL 2005特定的语法,但我认为你得到了正确的答案。
with segments (segment,startchain,endchain,lenchain,segnum)
as (select segment,startchain,endchain,lenchain
,row_number() over (partition by segment order by startchain,endchain) segnum
from stackchallenge)
select s1.segment,s1.startchain,s1.endchain,s1.lenchain
,case when s1.endchain = s2.startchain then 'WIN!'
when s1.endchain <> s2.startchain then 'FAIL!'
else '' end result
from segments s1
left join segments s2 on s1.segment = s2.segment
and s1.segnum + 1 = s2.segnum
以下是用于测试您需要SQL Server 2008直接使用的表和数据。如果您正在使用它,请更改Insert to SQL 2005语法。
create table stackchallenge (segment varchar(100),
startchain int,
endchain int,
result varchar(100),
lenchain int
)
insert into stackchallenge (segment,startchain,endchain,result,lenchain)
values
('ACACIA ST (KLN)' , 1073 , 1149 , 'FAIL!' , 76),
('ACACIA ST (KLN)' , 1073 , 1151 , 'FAIL!' , 78),
('ACACIA ST (KLN)' , 1150 , 1332 , 'FAIL!' , 182),
('ACACIA ST (KLN)' , 1151 , 1332 , 'FAIL!' , 181),
('ACACIA ST (KLN)' , 1606 , 2079 , '' , 473),
('ACTIVITY ST (WRK)' , 6 , 215 , 'WIN!' , 209),
('ACTIVITY ST (WRK)' , 215 , 227 , 'WIN!' , 12),
('ACTIVITY ST (WRK)' , 227 , 423 , 'WIN!' , 196),
('ACTIVITY ST (WRK)' , 423 , 549 , 'WIN!' , 126),
('ACTIVITY ST (WRK)' , 549 , 600 , '' , 51),
('ADRIENNE CT (WMN)' , 5 , 107 , 'WIN!' , 102),
('ADRIENNE CT (WMN)' , 107 , 122 , '' , 15),
('AERODROME RD (LYB)' , 0 , 140 , 'WIN!' , 140),
('AERODROME RD (LYB)' , 140 , 428 , 'WIN!' , 288),
('AERODROME RD (LYB)' , 428 , 716 , 'WIN!' , 288),
('AERODROME RD (LYB)' , 716 , 998 , 'WIN!' , 282),
('AERODROME RD (LYB)' , 998 , 1280 , 'WIN!' , 282),
('AERODROME RD (LYB)' , 1280 , 1566 , 'WIN!' , 286),
('AERODROME RD (LYB)' , 1566 , 1851 , 'WIN!' , 285),
('AERODROME RD (LYB)' , 1851 , 2136 , 'WIN!' , 285),
('AERODROME RD (LYB)' , 2136 , 2421 , '' , 285)
答案 1 :(得分:2)
假设不会有重复的行,以下内容应该是一个与数据库无关的合理解决方案:
select street, startno, endno,
case (select coalesce(min(s2.startno),-1) from stackchallenge s2
where s1.street = s2.street and
s1.startno <= s2.startno and
s1.endno < s2.endno)
when -1 then ' '
when endno then 'WIN!'
else 'FAIL!'
end as validated,
length
from stackchallenge s1 order by 1,2,3