Here is a problem. I have a table
flightdetails
-----------+-------------
flightName | varchar(200)
departure | date
arrival | date
I want to get all the flights in the given date range. Either fromDate or toDate should be inside the given daterange. I know of a simple query which will give me the result
select flightname from flightdetails where (departure between fromDate and toDate)
or (arrival between fromDate and toDate);
But this not good for performance as I use an OR condition. Can anyone suggest a better solution which favours performance too
This is a common solution to this problem. Each subquery can make use of an index this way.
select flightname from flightdetails where departure between fromDate and toDate
union
select flightname from flightdetails where arrival between fromDate and toDate;
Re comment from @SalmanA
You're right, the query above misses cases like this:
departure < fromDate < toDate < arrival
Since neither departure nor arrival are between the date range, but of course the date range is included in the flight time.
Here's another solution, based on yours but it makes use of indexes both on departure and arrival. Be sure to create compound indexes for each condition:
create index flt_d on flightdetails(flightname, departure);
create index flt_a on flightdetails(flightname, arrival);
select f1.flightname
from flightdetails f1
join flightdetails f2 use index (flt_a)
on f1.flightname = f2.flightname
where f1.departure <= toDate
and f2.arrival >= fromDate;
I tested this out and I had to use the "use index" hint to coax it to use the second index, but when I did I got this optimizer plan:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: f1
type: index
possible_keys: flt_d,flt_a
key: flt_d
key_len: 20
ref: NULL
rows: 3
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: f2
type: ref
possible_keys: flt_a
key: flt_a
key_len: 12
ref: test.f1.flightname
rows: 1
Extra: Using where; Using index
I think you could use this query:
-- 2.2) select date ranges that overlap [d1, d2] (d2 and end_date are inclusive) SELECT * FROM <table> WHERE @d2 >= start_date AND end_date >= @d1
Making few substitutions eg start_date becomes departure, end_date becomes arrival, etc:
SELECT flightname
FROM flightdetails
WHERE toDate >= departure AND arrival >= fromDate
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.