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
ref
field - if no matches in
ref
field, then match one_date+e_time+place
fields - if no matches on
ref
ore_date+e_time+place
then 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.