我有一张location_from,locations_to和航班计数的表格。我想将行距等于另一行的到达行组合在一起(例如LA TO NY与NY TO LA组合),然后对类似的行进行求和。
我认为最好举个例子来解释。
之前
locations_from locations_to # of Flights
--------------------------------------------------
San Francisco, CA Los Angeles, CA 29558
Los Angeles, CA San Francisco, CA 32389
New York, NY Los Angeles, CA 30389
Los Angeles, CA New York, NY 35484
Las Vegas, NV Los Angeles, CA 28363
Los Angeles, CA Las Vegas, NV 34455
Honolulu, HI Kahului, HI 46563
Kahului, HI Honolulu, HI 16879
San Francisco, CA New York, NY 44654
New York, NY San Francisco, CA 25882
之后
From/To From/To # of Flights
---------------------------------------------------
San Francisco, CA Los Angeles, CA 61947
New York, NY Los Angeles, CA 65873
Las Vegas, NV Los Angeles, CA 62818
Honolulu, HI Kahului, HI 63442
San Francisco, CA New York, NY 70536
我已经尝试过交叉连接
where a.locations_from = b.locations_to
这行得通,但我最终得到了两倍的行数(即LA TO NY的一列,NY TO LA的一列)
答案 0 :(得分:2)
只需使用CASE ... END
对机场进行“分类”,然后按该“已分类”对进行分组。
SELECT CASE
WHEN [locations_from] > [locations_to]
THEN [locations_to]
ELSE
[locations_from]
END [From/To],
CASE
WHEN [locations_from] > [locations_to]
THEN [locations_from]
ELSE
[locations_to]
END [From/To],
sum([# of Flights]) [# of Flights]
FROM elbat
GROUP BY CASE
WHEN [locations_from] > [locations_to]
THEN [locations_to]
ELSE
[locations_from]
END,
CASE
WHEN [locations_from] > [locations_to]
THEN [locations_from]
ELSE
[locations_to]
END;
这也是在相反方向上使用FULL JOIN
的替代解决方案。
SELECT coalesce(t1.[locations_from], t2.locations_from) [locations_from],
coalesce(t1.[locations_to], t2.locations_from) [locations_to],
coalesce(t1.[# of Flights], 0) + coalesce(t2.[# of Flights], 0) [# of Flights]
FROM elbat t1
FULL JOIN elbat t2
ON t2.[locations_from] = t1.[locations_to]
AND t2.[locations_to] = t1.[locations_from]
WHERE (t1.[locations_from] IS NULL
AND t1.[locations_to] IS NULL
OR t1.[locations_from] < t1.[locations_to])
AND (t2.[locations_from] IS NULL
AND t2.[locations_to] IS NULL
OR t2.[locations_from] > t2.[locations_to]);
答案 1 :(得分:2)
使用工会
Declare @YourTable Table (SomeRowID int,[locations_from] varchar(50),[locations_to] varchar(50),[# of Flights] int)
Insert Into @YourTable Values
(1,'San Francisco, CA','Los Angeles, CA',29558)
,(2,'Los Angeles, CA','San Francisco, CA',32389)
,(3,'New York, NY','Los Angeles, CA',30389)
,(4,'Los Angeles, CA','New York, NY',35484)
,(5,'Las Vegas, NV','Los Angeles, CA',28363)
,(6,'Los Angeles, CA','Las Vegas, NV',34455)
,(7,'Honolulu, HI','Kahului, HI',46563)
,(8,'Kahului, HI','Honolulu, HI',16879)
,(9,'San Francisco, CA','New York, NY',44654)
,(10,'New York, NY','San Francisco, CA',25882);
select [locations_from], [locations_to], sum([# of Flights])
from
(
select [locations_from], [locations_to], [# of Flights]
from @YourTable
where [locations_from] < [locations_to]
union all
select [locations_to], [locations_from], [# of Flights]
from @YourTable
where [locations_from] > [locations_to]
) t
group by [locations_from], [locations_to]
答案 2 :(得分:1)
另一个使用CROSS APPLY
和条件聚合的选项
此示例假定您具有某种RowID
示例
Declare @YourTable Table (SomeRowID int,[locations_from] varchar(50),[locations_to] varchar(50),[# of Flights] int)
Insert Into @YourTable Values
(1,'San Francisco, CA','Los Angeles, CA',29558)
,(2,'Los Angeles, CA','San Francisco, CA',32389)
,(3,'New York, NY','Los Angeles, CA',30389)
,(4,'Los Angeles, CA','New York, NY',35484)
,(5,'Las Vegas, NV','Los Angeles, CA',28363)
,(6,'Los Angeles, CA','Las Vegas, NV',34455)
,(7,'Honolulu, HI','Kahului, HI',46563)
,(8,'Kahului, HI','Honolulu, HI',16879)
,(9,'San Francisco, CA','New York, NY',44654)
,(10,'New York, NY','San Francisco, CA',25882)
;with cte as (
Select A.SomeRowID
,Loc1 = min(Loc)
,Loc2 = max(Loc)
,Flights = sum(Val)
From @YourTable A
Cross Apply ( values ([locations_from],[# of Flights])
,([locations_to] ,0)
) B (Loc,Val)
Group By A.SomeRowID
)
Select Loc1
,Loc2
,Flights=sum(Flights)
From cte
Group By Loc1,Loc2
返回
Loc1 Loc2 Flights
Honolulu, HI Kahului, HI 63442
Las Vegas, NV Los Angeles, CA 62818
Los Angeles, CA New York, NY 65873
Los Angeles, CA San Francisco, CA 61947
New York, NY San Francisco, CA 70536