2015-09-02 91 views
1

我創建了一個按點排序的排名查詢,然後如果它按創建日期排序。問題是,當我使用日期來訂購繪圖時,它會變得混亂。通過維護變量順序的SQL順序

這是我有什麼第一:

SELECT 
    @rownum := @rownum + 1 AS rank, 
    sticker_id, 
    total_shared, 
    total_liked, 
    total_used, 
    total_shared+total_liked+total_used AS points, 
    stickers.date 
FROM( 
    SELECT 
     sticker_id, 
     SUM(if(event_id = 1, 4, 0)) AS total_shared, 
     SUM(if(event_id = 2, 2, 0)) AS total_liked, 
     SUM(if(event_id = 3, 6, 0)) AS total_used 
    FROM stickers_stats 
    WHERE timestamp LIKE '2015-09%' 
    GROUP BY sticker_id 
) AS ranks 
JOIN (SELECT @rownum := 0) r 
INNER JOIN stickers 
    ON ranks.sticker_id = stickers.id 
ORDER BY points DESC 

結果:

First result


這是我得到了什麼之後:

SELECT 
    @rownum := @rownum + 1 AS rank, 
    sticker_id, 
    total_shared, 
    total_liked, 
    total_used, 
    total_shared+total_liked+total_used AS points, 
    stickers.date 
FROM( 
    SELECT 
     sticker_id, 
     SUM(if(event_id = 1, 4, 0)) AS total_shared, 
     SUM(if(event_id = 2, 2, 0)) AS total_liked, 
     SUM(if(event_id = 3, 6, 0)) AS total_used 
    FROM stickers_stats 
    WHERE timestamp LIKE '2015-09%' 
    GROUP BY sticker_id 
) AS ranks 
JOIN (SELECT @rownum := 0) r 
INNER JOIN stickers 
    ON ranks.sticker_id = stickers.id 
ORDER BY points DESC, stickers.date ASC 

結果: Second result

我試過改變字段顯示方式和所有內容的順序,但我找不到解決方案。如何通過pointsstickers.date訂購新的排名位置?

回答

1

當你開始將變量與其他結構混合時,MySQL可能會感到困惑。我不知道有什麼祕訣查詢在邊緣,但使用子查詢應該有所幫助:

SELECT @rownum := @rownum + 1 AS rank, t.* 
FROM (SELECT sticker_id, total_shared, total_liked, total_used, 
      (total_shared + total_liked + total_used) AS points, 
      s.date 
     FROM (SELECT sticker_id, 
        SUM(if(event_id = 1, 4, 0)) AS total_shared, 
        SUM(if(event_id = 2, 2, 0)) AS total_liked, 
        SUM(if(event_id = 3, 6, 0)) AS total_used 
      FROM stickers_stats 
      WHERE timestamp >= '2015-09-01' and timestamp < '2015-10-01' 
      GROUP BY sticker_id 
     ) r JOIN 
      stickers s 
      ON r.sticker_id = s.id 
    ) t CROSS JOIN 
    (SELECT @rownum := 0) params 
ORDER BY points DESC, date ASC; 

另外:

  • 不要使用LIKE日期/時間值。
  • 始終使用ON子句與JOIN。如果你想要一個CROSS JOIN,請明確。
+0

謝謝您的回答,它幫了我很多關於你的答案 – rafamds

1

我傾向於強制子查詢中的順序。它仍然沒有確定的工作(MySQL有一些在命令語句中的查詢語句會被執行),但似乎更可靠。

在這種情況下,我會建議你做的加入到子查詢中的貼紙,以及: -

SELECT 
    @rownum := @rownum + 1 AS rank, 
    sticker_id, 
    total_shared, 
    total_liked, 
    total_used, 
    total_shared+total_liked+total_used AS points, 
    stickers_date 
FROM( 
    SELECT 
     sticker_id, 
     stickers.date AS stickers_date, 
     SUM(if(event_id = 1, 4, 0)) AS total_shared, 
     SUM(if(event_id = 2, 2, 0)) AS total_liked, 
     SUM(if(event_id = 3, 6, 0)) AS total_used 
    FROM stickers_stats 
    INNER JOIN stickers 
    ON stickers_stats.sticker_id = stickers.id 
    WHERE YEAR(timestamp) = 2015 
    AND MONTH(timestamp) = 9 
    GROUP BY sticker_id, stickers_date 
    ORDER BY points DESC, stickers_date ASC 
) AS ranks 
CROSS JOIN (SELECT @rownum := 0) r 
ORDER BY points DESC, stickers.date ASC 
+0

謝謝,它幫助我很多。戈登更快;) – rafamds

+0

沒問題。戈登斯的回答可能很好,他應該接受,我只是希望強制子查詢中的順序,使它更明確,它是在一個已經有序的數據集計數。 – Kickstart

+0

是的,我明白你的觀點,我也同意這一點。乾杯 – rafamds