SQL命令通过维护变量顺序

时间:2015-09-02 11:17:51

标签: mysql sql sql-order-by

我创建了一个按点排序的排名查询,然后如果是抽奖,则按创建日期排序。问题是,当我使用日期来订购绘图时,它会搞砸。

这就是我的第一次:

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订购新的排名?

2 个答案:

答案 0 :(得分: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,请明确。

答案 1 :(得分:1)

我倾向于强迫子查询中的顺序。它仍然不确定是否有效(MySQL有一些关于订单语句的get子句将在查询中执行),但似乎更可靠。

在这种情况下,我建议你也在子查询中加入贴纸: -

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