我有一个按预期返回值的查询,但是ORDER BY似乎在最后一列(totalPointsSum)上是一个别名列。
下面显示了这些数据的外观示例。显然我想要6200第一,400秒和50第三个按totalPointsSum排序 - 任何关于我做错的想法?
+---------+----------+----------------+
| user_id | username | totalPointsSum |
| 5555555 | bob | 6200 |
| 6666666 | geoff | 50 |
| 7777777 | lee | 400 |
+---------|----------|----------------+
我的表格结构如下:
myusers(user_id, username);
organisations(organisation_id, organisation_name);
codes(redeemed_code_id, user_id, unique_code, date_redeemed, school_points, inactive);
我的查询如下..
SELECT
t.*, (
SELECT
COALESCE (SUM(x.school_points), "0")
FROM
codes x
WHERE
x.user_id = t.user_id
AND x.school_points > 0
AND x.inactive = 0
AND (
x.date_redeemed >= 1393286400
OR x.date_redeemed = 0
)
) AS totalPointsSum
FROM
`myusers` `t`
INNER JOIN organisation o ON (
t.organisation_id = o.organisation_id
)
WHERE
o.organisation_id = 25679
ORDER BY totalPointsSum desc
P.S我很快就会添加一个方便的
答案 0 :(得分:2)
问题在于这一行:
COALESCE (SUM(x.school_points), "0")
字符串"0"
强制内部查询(totalPointsSum
)计算的值的类型为字符串。因此,ORDER BY totalPointsSum desc
对字符串"6200"
,"50"
和"400"
进行排序并做得很好。
将"0"
(字符串)更改为0
(数字),查询将按您的意愿运行。
答案 1 :(得分:1)
看来你的内部SELECT的返回值被视为字符串而不是整数。
尝试添加零(这应该强制它被视为数字):
ORDER BY totalPointsSum+0 DESC
旁注:
您可以验证school_points
实际上是INT
字段。如果不是,只需将其更改为INT
字段即可。
答案 2 :(得分:1)
或者,从COALESCE
函数中的0周围删除双引号。这将消除正在发生的隐式数据转换,并允许表达式为数字。
COALESCE(SUM(x.school_points), 0 )
^ ^
您也可以使用MySQL IFNULL
函数
IFNULL(SUM(x.school_points),0)
无论哪种方式,这将是传递给外部查询的数字列,因此ORDER BY
将把它作为数字而不是字符串来处理。
对两个不同数据类型的表达式(例如数字和字符串)使用COALESCE
时,会有一个隐式转换,因此返回的列是单个数据类型。
您在原始陈述中发生的是隐式数据转换,基本上等同于显式表达:
COALESCE(CAST( SUM(x.school_points) AS VARCHAR(50)), '0')
^^^^^ ^^^^^^^^^^^^^^^
如果删除零附近的引号,则会将字符串文字中的零更改为数字文字。这意味着SUM()
不必转换为字符类型。
答案 3 :(得分:0)
请尝试ORDER BY LENGTH(totalPointsSum)desc,totalPointsSum desc;
这样可以模拟自然顺序。