SQL:如果字段为非null,我如何按字段排序,否则使用另一个字段

Jie*_*eng 10 mysql sql

我想排序我的Postsby dtModified(修改日期时间)如果它不为空(修改后的b4),否则排序依据dtPosted(发布日期时间)

Mar*_*ers 16

你可以使用COALESCE:

ORDER BY COALESCE(dtModified, dtPosted)
Run Code Online (Sandbox Code Playgroud)

另一个选择是使用MySQL特定的函数IFNULL而不是COALESCE.


测试MySQL:

CREATE TABLE table1 (dtModified DATETIME NULL, dtPosted DATETIME NOT NULL);
INSERT INTO table1 (dtModified, dtPosted) VALUES
('2010-07-31 10:00:00', '2010-07-30 10:00:00'),
(NULL                 , '2010-07-31 09:00:00'),
('2010-07-31 08:00:00', '2010-07-30 10:00:00');

SELECT dtModified, dtPosted
FROM table1
ORDER BY COALESCE(dtModified, dtPosted)
Run Code Online (Sandbox Code Playgroud)

结果:

dtModified           dtPosted
2010-07-31 08:00:00  2010-07-30 10:00:00
NULL                 2010-07-31 09:00:00
2010-07-31 10:00:00  2010-07-30 10:00:00
Run Code Online (Sandbox Code Playgroud)


pax*_*blo 5

好像我每周三次给出这个建议,也许我应该放弃并放手:-)不,我不这么认为:

order by如果希望数据库能够很好地扩展,请不要在列计算(或子句)中使用每行函数.您应该检查特定情况的性能(测量,不要猜测),但在读取数据库时进行计算通常会影响您的扩展能力(这对您的地址簿数据库无关紧要,但我工作的商店数量巨大)数据的).

"如何让我的数据库更快地运行?" 问题远远超过"我如何使用更少空间?"的数量.那些.这是牺牲磁盘空间以提高性能的良好途径.

正确的计算时间是数据的变化.这样,更改的成本将在所有读取中分摊.

我的建议是创建另一个列,例如dtLastAction包含排序值,然后使用insert/update触发器将其设置为dtModified如果不为null,或者dtPosted如果dtModified为null.从技术上讲,这违反了3NF,但如果您知道自己在做什么,那就没关系,并且在这种情况下触发器可以保证数据的一致性.

然后在dtLastAction列上编制索引,并在插入和更新期间以一些额外工作的(较低)成本查看查询速度.我说较少,因为绝大多数数据库表的读取频率高于写入(显然,如果您的特定情况是非常罕见的例外情况,则此方法无效).

或者,对于此特定情况,您可以在创建条目时设置dtModifieddtPosted使用相同的值,这意味着dtModified永远不会 null.您仍然可以检测到这两个日期时间值相同的事实从未被修改过的帖子.