问题
I work for a trucking company, and we're interested in getting a count of the number of times one of our trucks travels between two cities, in either direction.
I have a table that lists an origin and destination for each trip segment, such as:
Origin Destination
City 1 City 2 City 2 City 1 City 3 City 4 City 2 City 1
I need a query that tells me that there were three trips between City 1 and City 2 and one trip between City 3 and City 4. Thanks very much!
回答1:
I think the following should do the trick.
SELECT route , COUNT(1) FROM
(
SELECT
CASE WHEN Origin > Destination THEN Origin+'_'+Destination
ELSE Destination+'_'+Origin
END AS route
FROM table1
)a
GROUP BY route
回答2:
Here is a way by sorting the columns, sort of. Granted, I'd change the column names from the output to something other than Origin and Destination since were are basically turning it into a "route". Perhaps just concat them like a1ex07 did. I left it normalized in case you wanted to alter it.
declare @table table (Origin varchar(16), Destination varchar(16))
insert into @table
values
('City 1','City 2'),
('City 2','City 1'),
('City 3','City 4'),
('City 2','City 1')
;with cte as(
select
case when Origin > Destination then Origin else Destination end as Origin
,case when Destination < Origin then Destination else Origin end as Destination
from
@table)
select
Origin
,Destination
,count(Origin + Destination)
from
cte
group by
Origin
,Destination
回答3:
As they say, if you have right data structures, you usually get the right algorithms for free.
I'm guessing that your schema contains tables similar to the following:
create table City
(
id int primary key identity,
name nvarchar(100) not null
)
create table TravelLog
(
trip_id int primary key identity,
origin int foreign key references City,
destination int foreign key references City,
check (origin <> destination)
)
So, if you add the following two fields to your TravelLog table:
alter table TravelLog
add
low as case when origin <= destination then origin else destination end persisted,
high as case when origin >= destination then origin else destination end persisted
Then you can use the following simple query to get what you want:
with Q as
(
select count (*) as trips, low, high from TravelLog group by low, high
)
select Q.trips, o.name point_A, d.name point_B from Q
inner join City o on o.id = Q.low
inner join City d on d.id = Q.high
As a side benefit, you can use that same query to filter by driver, date, etc.
来源:https://stackoverflow.com/questions/45578075/how-to-get-count-of-two-way-combinations-from-two-columns