問題
有這么一個需求,需要根據訂單的創建時間和更新時間排序,要按照最后的操作時間進行排序。
比如,在26分創建了一個訂單a,在27分創建了一個訂單b,然后在28分修改訂單a,又在29分創建了訂單c,那么此時訂單的排序結果,應該是c,a,b。
表中數據(時間是示例,實際是datetime.datetime類型):
ID | 訂單號 | 創建時間 | 更新時間 |
---|---|---|---|
1 | a | 26 | 28 |
2 | b | 27 | |
3 | c | 29 |
方案
一開始的想法是根據更新時間排序,然后更新時間為空的,按照創建時間排序。但是這種方式對於沒有更新時間的數據,篩選出來會出現排序混亂的問題。
后來想到可以將兩個字段合成一個字段,這樣就可以對這個字段排序了,但是也有問題,合成一個字段,會出現數據重復,而且也不好篩選和過濾。
在網上搜了搜,看到可以使用SQL的條件表達式,case,when,then。
實現
SQL使用條件表達式,可以判斷update_time是否為空,如果有值,則使用自己的值,如果沒有值則使用create_time,並且可以對結果使用別名,然后根據這個別名來進行排序。這樣排序的時候就會同時根據更新時間和創建時間來排序。
代碼示例
完整代碼示例:
from django.db.models import Case, DateTimeField, F, When
# 查詢所有的數據,只要queryset是Django查詢集即可
queryset = Order.objects.all()
#
queryset.annotate(
op_time=Case(
When(update_time=F("update_time"), then=F("update_time"),),
default=F("create_time"),
output_field=DateTimeField(),
),
).order_by("-op_time")
完整的SQL示例:
SELECT
id,
create_time,
update_time,
(
CASE update_time
WHEN update_time THEN
update_time
ELSE
create_time
END) AS t
FROM
courtesy_car_order
ORDER BY
t DESC