与下表类似的数据:
| 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 |
在 MySQL子句 中仅获得一系列条件(具有降序重要性)的第一个匹配项的最佳方法是什么?WHERE
- 匹配
ref
字段 - 如果字段中没有匹配
ref
项,则匹配e_date+e_time+place
字段 - 如果没有匹配
ref
或e_date+e_time+place
然后匹配e_date+place+person
此处的目的是获得最佳单行匹配 - 基于一系列递减的标准 - 并且仅在不满足前面的标准时使用该标准。
我第一次尝试查询看起来像:
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')
)
但由于OR
是包容性的(不是顺序的),这会返回 rows 10
,25
并且37
- 见这个 sqlfiddle
我可以ORDER BY ref DESC
并且LIMIT 1
(如果我修改为SELECT id, ref FROM...
),但如果我没有ref
价值并且必须通过第二个或第三个条件中的任何一个来区分,那对我没有帮助
IF
我的下一次尝试在WHERE
子句中使用嵌套条件,例如:
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'
)
)
)
但是,这也会返回 rows 10
,25
并且37
- 请参阅此 sqlfiddle
还尝试使用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')
)
返回行10
和25
- 看到这个 sqlfiddle
编写此查询的最佳方法是什么?
我正在使用 php——我可以运行 3 个单独的顺序查询并对每个结果使用 php 条件——但我想使用单个 db 查询,因为该代码每小时运行数百万次。