在SQL Server的主表中查找与另一个表中的记录匹配的记录
我有一个SQL Server数据库,其中有三个表:Trips、Slices和Legs 每次行程与切片有一对多关系,切片与腿部有一对多关系 Trips表示完整行程,切片仅表示行程的出站或返回部分,支腿表示出站或返回切片中的所有站点 我希望能够找到所有腿匹配的旅行 以下是表格: 行程:在SQL Server的主表中查找与另一个表中的记录匹配的记录,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有一个SQL Server数据库,其中有三个表:Trips、Slices和Legs 每次行程与切片有一对多关系,切片与腿部有一对多关系 Trips表示完整行程,切片仅表示行程的出站或返回部分,支腿表示出站或返回切片中的所有站点 我希望能够找到所有腿匹配的旅行 以下是表格: 行程: tripId saleTotal queryDate 1 $200 6/10/2015 2 $198 6/11/2015 sliceId
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
legId carrier flightNumber departureAirport departureDate ArrivalAirport ArrivalDate sliceIDFK
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
切片:
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
legId carrier flightNumber departureAirport departureDate ArrivalAirport ArrivalDate sliceIDFK
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
腿:
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
legId carrier flightNumber departureAirport departureDate ArrivalAirport ArrivalDate sliceIDFK
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
我如何通过搜索出发机场/抵达机场(JFK/FRA),找到所有承运人和航班号匹配的所有行程,如在legId 1-4中
换句话说,legId 1-4是一个具有行程1详细信息的机组,而legId 5-7是另一个具有行程2详细信息的机组。我需要找到其他哪些旅行完全符合合法的1-4细节(PK和FK除外),等等。任何帮助都将不胜感激 哎呀,我的脑子疼
将所有问号(其中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
查询的内容是和notexists
子句。它们获取一次行程的航段数据,并使用except
子句有效地减去另一次行程的航段数据。如果没有留下任何信息,则第二个行程数据包含所有第一个行程数据。您必须运行两次和not exists
子句(操作数反转),以确保两组跳闸数据完全相同,并且其中一组不仅仅是另一组的子集
这无法扩展到大量行。希望这有帮助
只需传递要与之比较其他记录的基本TripId(在@BaseTripID中)。我假设您只关心承运人、航班号、出发机场、到达机场,以便与任何其他旅行完全匹配,而不考虑日期字段
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
create table Trips(tripId int、saleTotal int、queryDate)
创建表切片(切片ID int、连接int、持续时间int、tripIdFK int)
创建表腿(legId int、carrier char(2)、flightNumber int、出发机场char(3)、出发日期、抵达港口char(3)、抵达日期、sliceIDFK int)
插入Trips值(1200,'6/10/2015')、(2198,'6/11/2015')、(3300,'6/15/2015')、(4200,'6/21/2015'))
在切片中插入值(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)
插入Legs值(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)
--从行程中选择*
--从切片中选择*
--从Legs中选择*
-------------------------------------------------------------------
声明@BaseTripID int=1、@Legs int、@MatchingTripID int
声明@BaseTrip表(承运人字符(2),航班号整数,出发机场字符(3),到达港口字符(3),行号整数)
声明@MatchingTrip表(承运人字符(2)、航班号整数、出发机场字符(3)、到达机场字符(3)、行号整数、合法整数、tripid整数)
插入@BaseTrip
选择承运人、航班号、出发机场、到达机场、行号()
从支腿l连接s上的切片s.sliceId=l.sliceIDFK
其中s.tripIdFK=@BaseTripID
从@BaseTrip中选择@Legs=count(*)
插入@MatchingTrip
选择承运人、航班号、离港机场、到达港、行号()作为行号、行号、行号
从支腿l连接s上的切片s.sliceId=l.sliceIDFK
和s.tripIdFK在一起
(选择s.tripIdFK
从支腿l连接s上的切片s.sliceId=l.sliceIDFK
和s.tripIdFK@BaseTripID
由s.tripIdFK分组,计数(l.legId)=@腿数)
选择@MatchingTripID=m.tripid
从@MatchingTrip m加入@BaseTrip b
在m.carrier=b.carrier上
m.flightNumber=b.flightNumber
m.departureAirport=b.departureAirport
m.ArrivalAirport=b.ArrivalAirport
m.row_no=b.row_no
按m.tripid分组,具有COUNT(*)=@Legs
选择s.tripIdFK作为匹配的TripID、l.legid、l.carrier、l.flightNumber、l.departureAirport、l.ArrivalAirport
从腿到腿
在s.sliceId=l.sliceIDFK上连接切片s
其中s.tripIdFK=@MatchingTripID
---------------------
升降台行程
放下桌子切片
放下桌腿
利用腿数是关键。因此,我们消除了除了完全相同的腿以外的任何匹配(第4次旅行只有两条匹配的腿)。所以现在我们只得到trip3作为匹配记录
请注意,我们也不包括行程,除了匹配的行程外,还有其他行程。我希望这就是您所期望的,一对完全相同的行程。另一种方法是确定/存储每个片段的legsKey,以便您可以在行程中找到匹配的片段 对于每个片段,您的legsKey是每个航段的承运商和附加的航班号,您可以使用XML路径来完成,如 比如:
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
您正在使用哪些RDBMS?你尝试过什么?MSSQL 2012。我尝试了一些问题,但还没有解决它,这就是为什么我没有费心发布它们