我有一个包含三个表的SQL Server数据库: Trips ,切片和 Legs 。
每次旅行与切片有一对多的关系,而切片与 Legs 。
Trips表示完整行程,切片仅表示行程的出站或返回部分,而行表示出站或返回切片中的所有停靠点。
我希望能够找到匹配腿的所有旅程。
以下是表格:
行程:
__atomic_add_fetch
片:
tripId saleTotal queryDate
1 $200 6/10/2015
2 $198 6/11/2015
腿:
sliceId connections duration tripIdFK
1 1 50 1
2 1 45 1
3 0 60 2
4 1 85 2
我如何能够通过搜索departureAirport / arrivalAirport(JFK / FRA)找到所有航空公司和航班号匹配的所有航班,例如legId 1-4?
换句话说,legId 1-4是一个单元,其中Trip 1和legId 5-7的详细信息是另一个单元,其中包含Trip 2的详细信息。我需要查找哪些其他行程完全匹配legId 1-4详细信息(除了PK和FK)等。任何帮助将不胜感激!!
答案 0 :(得分:2)
希望这有帮助。
只需传递要与之比较其他记录的基本TripId(在@BaseTripID中)。我假设您只关心航空公司,flightNumber,departureAirport,ArrivalAirport,与任何其他旅行完全匹配,无论日期字段如何。
create table Trips(tripId int,saleTotal int,queryDate date)
create table Slices(sliceId int ,connections int,duration int ,tripIdFK int)
create table Legs(legId int, carrier char(2), flightNumber int, departureAirport char(3), departureDate date, ArrivalAirport char(3), ArrivalDate date, sliceIDFK int)
insert into Trips values(1,200,'6/10/2015'),(2,198,'6/11/2015'),(3,300,'6/15/2015'),(4,200,'6/21/2015')
insert into Slices values(1,1,50,1),(2,1,45,1),(3,0,60,2),(4,1,85,2),(5,1,50,3),(6,1,45,3),(7,1,45,4),(8,1,45,4)
insert into Legs values(1,'AA',1,'JFK','7/1/2015','LON','7/2/2015',1) ,
(2,'AA',2,'LON','7/2/2015','FRA','7/2/2015',1),
(3,'AA',11,'FRA','7/10/2015','LON','7/10/2015',2),
(4,'AA',12,'LON','7/10/2015','JFK','7/10/2015',2),
(5,'UA',5,'EWR','8/1/2015','LAX','8/1/2015',3),
(6,'UA',6,'LAX','8/5/2015','ORD','8/5/2015',4),
(7,'UA',7,'ORD','8/5/2015','EWR','8/5/2015',4),
(8,'AA',1,'JFK','7/11/2015','LON','7/12/2015',5),
(9,'AA',2,'LON','7/12/2015','FRA','7/12/2015',5),
(10,'AA',11,'FRA','7/20/2015','LON','7/20/2015',6),
(11,'AA',12,'LON','7/20/2015','JFK','7/20/2015',6),
(12,'AA',1,'JFK','7/1/2015','LON','7/2/2015',7) ,
(13,'AA',2,'LON','7/2/2015','FRA','7/2/2015',7),
(14,'AA',11,'FRA','7/10/2015','BEL','7/10/2015',8),
(15,'AA',12,'BEL','7/10/2015','JFK','7/10/2015',8)
--select * from Trips
--select * from Slices
--select * from Legs
-------------------------------------------------------------------
Declare @BaseTripID int = 1, @Legs int ,@MatchingTripID int
declare @BaseTrip table(carrier char(2), flightNumber int, departureAirport char(3), ArrivalAirport char(3),row_no int)
declare @MatchingTrip table(carrier char(2), flightNumber int, departureAirport char(3), ArrivalAirport char(3),row_no int,legid int,tripid int)
insert into @BaseTrip
select carrier, flightNumber, departureAirport, ArrivalAirport,ROW_NUMBER() over(order by l.legId)
from Legs l join slices s on s.sliceId = l.sliceIDFK
where s.tripIdFK = @BaseTripID
select @Legs=count(*) from @BaseTrip
Insert into @MatchingTrip
select carrier, flightNumber, departureAirport, ArrivalAirport,ROW_NUMBER() over(partition by s.tripIdFK order by l.legId) as row_no,l.legId,s.tripIdFK
from Legs l join slices s on s.sliceId = l.sliceIDFK
and s.tripIdFK in
(select s.tripIdFK
from Legs l join slices s on s.sliceId = l.sliceIDFK
and s.tripIdFK <> @BaseTripID
Group by s.tripIdFK having count(l.legId)=@Legs)
select @MatchingTripID = m.tripid
from @MatchingTrip m join @BaseTrip b
on m.carrier = b.carrier
and m.flightNumber = b.flightNumber
and m.departureAirport = b.departureAirport
and m.ArrivalAirport = b.ArrivalAirport
and m.row_no = b.row_no
GROUP BY m.tripid HAVING COUNT(*) = @Legs
select s.tripIdFK as matchingTripID,l.legid,l.carrier,l.flightNumber,l.departureAirport,l.ArrivalAirport
from Legs l
join Slices s on s.sliceId = l.sliceIDFK
where s.tripIdFK = @MatchingTripID
---------------------
drop table Trips
drop table Slices
drop table Legs
利用腿部计数是关键。因此,除了完全相同的腿之外,我们正在消除任何匹配(只有两条匹配腿的行程4)。所以现在我们只获得Trip 3作为匹配记录。
请注意,我们也排除了旅行,除了匹配的旅行之外还有任何额外的航程。我希望这是你所期待的,一对完全相同的旅程。
答案 1 :(得分:1)
噢,我的大脑疼!...
将所有问号(其中3个)替换为您要检查类似行程的行程ID。
select distinct s.tripIDFK as tripId
from Legs l
left join Slices s on l.sliceIDFK = s.sliceId
where s.tripIDFK != ?
and not exists (
select carrier, flightNumber, departureAirport, departureDate
from Legs l2
left join Slices s2 on l2.sliceIDFK = s2.sliceId
where s2.tripIDFK = s.tripIDFK
except
select carrier, flightNumber, departureAirport, departureDate
from Legs l2
left join Slices s2 on l2.sliceIDFK = s2.sliceId
where s2.tripIDFK = ?
)
and not exists (
select carrier, flightNumber, departureAirport, departureDate
from Legs l2
left join Slices s2 on l2.sliceIDFK = s2.sliceId
where s2.tripIDFK = ?
except
select carrier, flightNumber, departureAirport, departureDate
from Legs l2
left join Slices s2 on l2.sliceIDFK = s2.sliceId
where s2.tripIDFK = s.tripIDFK
)
order by s.tripIDFK
查询的内容是and not exists
子句。他们获得一次旅行的腿部数据,并使用except
子句有效地减去另一次旅行的腿部数据。如果您没有任何东西,则第二行程数据包含所有第一行程数据。您必须运行and not exists
子句两次(操作数反转)以确保两组行程数据真正相同,并且一个不仅仅是另一组的子集。
这绝不可扩展到大量行。
答案 2 :(得分:0)
另一种方法是确定/存储每个切片的legsKey,这样您就可以在不同的行程中找到匹配的切片。
对于每个切片,您的legsKey是附加的每个腿的载体和航班号,您可以使用For XML Path来执行此操作,例如this
类似的东西:
select
distinct
stuff((
select ',' + l.carrier + ':' + l.flightNumber
from legs l
where l.carrier = carrier and l.flightnumber = flightnumber
order by l.carrier, l.flightnumber
for xml path('')
),1,1,'') as legsList
from legs
group by carrier, flightnumber