2011-04-18 26 views
2

我想查詢數據庫表在Django有(其中包括)以下的列:Django的選擇查詢時間DIFF

id | start_time | end_time 

而不是獲取不同的值兩個,我剛剛得到的差異直接在查詢中? 東西到這種效果:

SELECT id, Diff(start_time, end_time) FROM myTable 

回答

2

QuerySet.extra()將允許您爲字段指定任意表達式。請注意,結果將取決於數據庫。

+0

既然問這個問題,我已經改變了我的桌子的設計,我只是用原始的SQL無妨;但我覺得這正是我在django文檔中尋找的信息的寶石,並且找不到!謝謝! – chandsie 2011-04-19 01:14:55

1

這在我看來,最簡單的辦法就是用差增加第三個字段,每個對象被修改像這一次更新:

class Timer(models.Model) 

    start_time = models.DateTimeField() 
    end_time = models.DateTimeField() 
    diff_time = models.DateTimeField() 

    def __init__(self, *args, **kwargs): 
     super(Timer, self).__init__(*args, **kwargs) 
     self.diff_time = self.end_time - self.start_time 

    def save(self, *args, **kwargs): 
     self.diff_time = self.end_time - self.start_time 
     super(Timer, self).save(*args, **kwargs) 

我試圖尋找與註釋的解決方案,但是在mysql和postgres中都不支持聚合函數。即使在那裏,看起來像是一個額外的列,不必計算每個查詢中每行的差異!

哦,你可以獲取你想要的東西是這樣的:

Timer.objects.values('id', 'diff_time') 
+1

對我來說,這只是一個糟糕的桌子設計。爲什麼要在我的表格中添加一列來保存冗餘數據?從數據建模的角度來看,它不僅愚蠢地保存冗餘數據,而且該解決方案也降低了我的應用程序的可擴展性。 – chandsie 2011-04-19 01:15:29

+1

我不得不同意建模的觀點,它是一種去規範化(事實根本不隱藏)。但從可擴展性的角度來看,我認爲你錯了。每當你使用差異進行查詢時,他們會更快,這就是可擴展性的全部。 – fceruti 2011-04-19 11:55:24

+0

你說得對,查詢確實會更快。當我將數據存儲到表中時,只會增加開銷,但單個記錄插入開銷顯然不如處理整個表內容的開銷「有害」。用戶在創建數據時甚至不會注意到延遲。 – chandsie 2011-04-20 04:21:09

0

由於Django的1.8,extra is discouraged贊成annotate + RawSQL的。以下爲MySQL的工作:

res = MyTable.objects.annotate(duration=RawSQL('datediff(endtime, starttime)',())) 
# examine the results 
print res.values_list('duration', 'starttime', 'endtime') 
2

這可以完全通過Django 1.10及以上的ORM完成。隨着像這樣一個模型:

class Timer(models.Model) 

    start_time = models.DateTimeField() 
    end_time = models.DateTimeField() 

您可以用時間註釋的對象,像這樣:

from django.db.models import DurationField, ExpressionWrapper, F 

Timer.objects.annotate(duration=ExpressionWrapper(F('end_time') - F('start_time'), 
                output_field=DurationField())) 
+0

從Django 1.10開始,這應該是實現OP要求的首選方式。或者,您可以跳過'ExpressionWrapper'並簡單地使用'Timer.objects.annotate(duration = F('end_time') - F('start_time'))''。在這種情況下,'duration'將以微秒爲單位包含'end_time'和'start_time'之間的差異。 – iulian 2016-11-08 16:36:49