With data similar to the table below:
| id | e_date | e_time | place | person| ref |ref_type|
| 10 | 2015-08-03 | 10:30 | work | tony | 1234 | A |
| 25 | 2015-08-03 | 10:30 | work | NULL | NULL | A |
| 37 | 2015-08-03 | NULL | work | tony | NULL | A |
| 99 | 2015-08-03 | 10:30 | work | fred | 1234 | B |
What's the best method to get only the 1st match of a series of conditions (of desc importance) in a MySQL WHERE clause ?
- match the
reffield - if no matches in
reffield, then match one_date+e_time+placefields - if no matches on
refore_date+e_time+placethen match one_date+place+person
The aim here is to get the best single row match - based on a descending series of criteria - and only use the criteria if the preceding criteria isn't fulfilled.
My first attempt at query looked like:
SELECT id FROM my_table
WHERE ref_type = 'A' AND (
ref = '1234'
OR
(e_date = '2015-08-03' AND e_time = '10:30' AND place = 'work')
OR
(e_date = '2015-08-03' AND place = 'work' AND person = 'tony')
)
but since OR is inclusive (not sequential), this returns rows 10, 25 and 37 - see this sqlfiddle
I could ORDER BY ref DESC and LIMIT 1 (if I modify to SELECT id, ref FROM...) but that doesn't help me if I have no ref value and have to differentiate by either of the 2nd or 3rd conditions
My next attempt uses nested IF conditions in the WHERE clause like :
SELECT id FROM my_table
WHERE ref_type = 'A' AND (
IF(ref = 1234,
ref = 1234,
IF(e_date = '2015-08-03' AND e_time = '10:30' AND place = 'work',
e_date = '2015-08-03' AND e_time = '10:30' AND place = 'work',
e_date = '2015-08-03' AND place = 'work' AND person = 'tony'
)
)
)
However, this returns also rows 10, 25 and 37 - see this sqlfiddle
Also tried using IFNULL :
SELECT id FROM my_table
WHERE ref_type = 'A' AND
IFNULL(ref = '1234',
IFNULL(e_date = '2015-08-03' AND e_time = '10:30' AND place = 'work',
e_date = '2015-08-03' AND place = 'work' AND person = 'tony')
)
Which returns rows 10 and 25 - see this sqlfiddle
What's the best way to write this query ?
I'm using php - and I could run 3 separate sequential queries and use php conditionals on each result - but I'd like to use a single db query given the millions of times this code will be run per hour.