SQL order by maintain variable order
SQL order by maintain variable order
我创建了一个按分数排序的排名查询,然后如果是平局则按创建日期排序。问题是当我使用日期来订购抽奖时,它变得一团糟。
这是我的第一个:
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
结果:
这是我得到的:
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
结果:
我试过更改字段的显示顺序和所有内容,但找不到解决方案。如何按 points
和 stickers.date
以新排名位置排序?
当您开始将变量与其他结构混合时,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
用于 date/time 值。
- 总是在
JOIN
中使用 ON
子句。如果你想要 CROSS JOIN
,请明确。
我倾向于在子查询中强制排序。它仍然不确定是否有效(MySQL 有一些关于订单语句的 get out 子句将在查询中执行),但似乎更可靠。
在这种情况下,我建议您在子查询中也加入贴纸:-
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
我创建了一个按分数排序的排名查询,然后如果是平局则按创建日期排序。问题是当我使用日期来订购抽奖时,它变得一团糟。
这是我的第一个:
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
结果:
这是我得到的:
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
结果:
我试过更改字段的显示顺序和所有内容,但找不到解决方案。如何按 points
和 stickers.date
以新排名位置排序?
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
用于 date/time 值。 - 总是在
JOIN
中使用ON
子句。如果你想要CROSS JOIN
,请明确。
我倾向于在子查询中强制排序。它仍然不确定是否有效(MySQL 有一些关于订单语句的 get out 子句将在查询中执行),但似乎更可靠。
在这种情况下,我建议您在子查询中也加入贴纸:-
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