2011-11-17 113 views
0

我想按視圖/下載對圖像列表進行排序。我將統計信息存儲在不同的表中,每天保存一行。經過幾天的搜索,我設法得到了一個可用的SQL,但由於我幾乎做了3次相同的查詢,因此效率不高。這裏是我的表和SQL:如何從一個子查詢中選擇多個列而不是多個相似的子查詢?

CREATE TABLE "images_stats" (
    "id" integer NOT NULL PRIMARY KEY, 
    "image_id" integer NOT NULL REFERENCES "images_image" ("id"), 
    "date" date NOT NULL, 
    "view_count" integer unsigned NOT NULL, 
    "download_count" integer unsigned NOT NULL 
) 

images_list = Images.objects.raw(''' 
    SELECT *, 
     (SELECT 1.0*SUM(s.view_count)/SUM(s.download_count) 
     FROM images_stats AS s 
     WHERE s.image_id = w.id AND s.date < %s AND s.date >= %s) AS ratio, 
     (SELECT 1.0*SUM(s.view_count)/SUM(s.download_count) 
     FROM images_stats AS s 
     WHERE s.image_id = w.id AND s.date < %s) AS global_ratio, 
     (SELECT COUNT(*)==0 
     FROM images_stats AS s 
     WHERE s.image_id = w.id AND s.date < %s) AS count 
    FROM images_image as w 
    WHERE w.category_id = %s 
    ORDER BY count, ratio, global_ratio 
''', [date.today(), date.today()-timedelta(days=1), date.today(), date.today(), category.id]) 

有誰知道我該如何優化這個SQL?我有一些SQL知識,但顯然不夠。

回答

0
SELECT *, 
    SUM(case when s.date < %s AND s.date >= %s then s.view_count else 0 end)/ 
    SUM(case when s.date < %s AND s.date >= %s then s.download_count else 0 end) 
     AS ratio, 
    SUM(case when s.date < %s then s.view_count else 0 end)/ 
    SUM(case when s.date < %s then s.download_count else 0 end) 
     AS global_ratio, 
    COUNT(*)==0 AS count 
FROM images_image as w 
LEFT JOIN images_stats AS s 
    ON s.image_id = w.id 
WHERE w.category_id = %s 
GROUP BY w.id 
ORDER BY count, ratio, global_ratio 
+0

看起來很乾淨,但它不起作用。我得到比例:無以及global_ratio:無。我剛剛意識到我的代碼不工作,因爲我得到重複的圖像,我甚至嘗試添加組,但不會幫助。 – andrei