Reputation: 403
I hope someone can help me. I've looked at other threads but I was not able to find the right answer.
I have a mysql database with the following data:
id, company, datefrom, dateto, rate, point1, point2
1, DHL, 2014-03-01, 2014-03-31, $1000, Paris, New York
2, MRW, 2014-03-01, 2014-03-31, $1300, Paris, New York
3, EXP, 2014-03-01, 2014-03-31, $1000, Paris, New York
4, DHL, 2014-03-06, 2014-03-31, $900, Paris, New York
5, FED, 2014-03-01, 2014-03-31, $1200, Paris, New York
I need to do a query where, based on the date, it will display only those rates valid on that date onwards. For example if today is 2014-03-06, I need the result to be :
2, MRW, 2014-03-01, 2014-03-31, $1300, Paris, New York
3, EXP, 2014-03-01, 2014-03-31, $1000, Paris, New York
4, DHL, 2014-03-06, 2014-03-31, $900, Paris, New York
5, FED, 2014-03-01, 2014-03-31, $1200, Paris, New York
As you can see, record 1 is not displayed as record 4 replaces record 1 as of 2014-03-06
I have tried the following query, which worked:
SELECT id, company, MAX(datefrom), dateto, rate, point1, point2 FROM mydatabase
WHERE datefrom<='2014-03-06' and datefrom>='2014-03-06'
AND point1='Paris' AND point2='New York' GROUP BY company, point1, point2
This query works great EXCEPT that it selects all companies but for DHL, it selects all fields from record 1 BUT the datefrom from record 4 !
What am I doing wrong?
Upvotes: 2
Views: 51
Reputation: 24134
You need to add condition of not existing record with datefrom
after current record datefrom
.
select * from mydatabase t1
WHERE '2014-03-06' between datefrom and dateto
AND NOT EXISTS
(
select 1 from mydatabase
where company=t1.company
AND point1 = t1.point1
AND point2 = t1.point2
AND '2014-03-06' between datefrom and dateto
AND datefrom>t1.datefrom
)
Upvotes: 0
Reputation: 424953
Make use of mysql's non-standard grouping support:
SELECT * FROM (
SELECT * FROM mydatabase
WHERE '2014-03-06' BETWEEN datefrom AND dateto
AND point1 = 'Paris'
AND point2 = 'New York'
ORDER BY datefrom DESC) x
GROUP BY company
This works by first ordering matching rows by latest-starting range first in the inner query, then by grouping by not all non-aggregate columns, mysql selects the first row for each unique value of company
, the first row being the one you want (having previously been ordered).
Note also the reworking of the condition to use BETWEEN
which is more elegant.
Upvotes: 1