好的,这是我的问题:
SELECT NAME,
DATE_FORMAT(DATE_WRITTEN, "%c/%e/%y") AS written_date,
DATE_FORMAT(RETURN_DATE, "%c/%e/%y") AS return_date
FROM `pfp`.`returns` AS `Re`
LEFT JOIN `pfp`.`insurance` AS `Insurance`
ON ( `insurance`.`id` = `Re`.`INSURANCE_ID` )
LEFT JOIN `pfp`.`remain` AS `Remain`
ON ( `remain`.`id` = `Re`.`REMAIN_ID` )
LEFT JOIN `pfp`.`formula` AS `Formula`
ON ( `formula`.`id` = `remain`.`FORMULA_ID` )
WHERE `NOT_RETURNED` = 'F'
AND `RETURN_DATE` BETWEEN '2014-01-01' AND '2014-08-22'
ORDER BY `RETURN_DATE` DESC
LIMIT 100
问题在于它在14-8-9之前排序到14-8-7然后再跳回到14-8-22然后从那里向下......为什么?
答案 0 :(得分:2)
按return_date
排序时,您按格式化的别名排序。相反,使用表别名来标识您确实需要该列:
WHERE `NOT_RETURNED` = 'F'
AND `RETURN_DATE` BETWEEN '2014-01-01' AND '2014-08-22'
ORDER BY re.RETURN_DATE DESC
LIMIT 100
我猜它在re
表中。使用适当的别名。
编辑:
首先搜索列别名的事实是documented:
MySQL解析ORDER BY中的非限定列或别名引用 通过在select_expr值中搜索,然后在列中的子句 FROM子句中的表。对于GROUP BY或HAVING子句,它 在搜索select_expr值之前搜索FROM子句。 (对于GROUP BY和HAVING,这与MySQL 5.0之前的行为不同 使用与ORDER BY相同的规则。)
我可以推测出这个原因(我认为这符合ANSI标准)。 SQL查询按照特定顺序进行逻辑处理,例如from
,然后是where
,然后是select
,然后是order by
(省略其他条款) )。此逻辑处理确定如何编译查询以及标识符的含义。逻辑处理解释了为什么where
子句中不允许列别名 - 从编译器的角度来看,它们尚未被识别。
当谈到order by
时,标识符由内而外确定。第一个定义是select
中的版本,因此在转到from
之前选择该版本。