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

时间:2010-07-31 11:21:57

标签: sql mysql

我希望PostsdtModified(修改日期时间)排序,如果它不为空(修改后的b4),则按dtPosted排序(发布日期时间)

3 个答案:

答案 0 :(得分:16)

您可以使用COALESCE

ORDER BY COALESCE(dtModified, dtPosted)

另一种选择是使用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)

结果:

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

答案 1 :(得分:5)

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

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

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

进行计算的正确时间是数据发生变化时。这样,更改的成本就会在所有读取中分摊。

我的建议是创建另一个列,例如dtLastAction以包含排序值,然后使用插入/更新触发器将其设置为与dtModified相同(如果不为空)或{{1}如果dtPosted为空。从技术上讲,这违反了3NF,但如果您知道自己在做什么就可以了,并且在这种情况下触发器可以保证数据的一致性。

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

或者,对于这种特殊情况,您可以在创建条目时将dtLastActiondtModified设置为相同的值,这意味着dtPosted永远不会 空值。您仍然可以检测到这两个日期时间值相同的事实从未被修改的帖子。

答案 2 :(得分:0)

在SELECT中,使用CASE语句,如果不为null则采用修改日期的值,否则发布日期。然后为您的ORDER BY使用新的“计算”列。

相关问题