Php MySQL查询-如何以某种方式对结果排序

Php MySQL查询-如何以某种方式对结果排序,php,mysql,database,sorting,Php,Mysql,Database,Sorting,以下是我到目前为止的预览: MySQL表: 我想做的是能够以某种方式对其进行排序。我希望所有“免费”的行都位于最顶端,因此“特价”等于0.00 我也希望所有有特殊价格的行都在那之后,然后所有有正常价格的行都在那之后。有没有办法在不指定排序id的情况下执行此操作,这样用户就不必自己更改顺序 因此,在上述示例中,最后一个字段“测试”将上移一个字段,“更换空气滤清器”将是最后一个字段 现在在我的查询中没有orderby,所以它是按id排序的 感谢您的帮助。谢谢 ORDER BY COALESCE(

以下是我到目前为止的预览:

MySQL表:

我想做的是能够以某种方式对其进行排序。我希望所有“免费”的行都位于最顶端,因此“特价”等于0.00

我也希望所有有特殊价格的行都在那之后,然后所有有正常价格的行都在那之后。有没有办法在不指定排序id的情况下执行此操作,这样用户就不必自己更改顺序

因此,在上述示例中,最后一个字段“测试”将上移一个字段,“更换空气滤清器”将是最后一个字段

现在在我的查询中没有orderby,所以它是按id排序的

感谢您的帮助。谢谢

ORDER BY COALESCE(special_price,99999) ASC, price ASC
我们应该做到这一点

解释
COALESCE
是一个接受第一个非空值的函数,因此,如果您有空的特殊价格,它将默认为
99999
(只是在订购结束时获取的任意高数值)。从那里我们按价格订购,所以任何领带,以及清单的末尾,都将按价格升序排列

我们应该做到这一点

解释
COALESCE
是一个接受第一个非空值的函数,因此,如果您有空的特殊价格,它将默认为
99999
(只是在订购结束时获取的任意高数值)。从那里我们可以按价格订购,因此任何领带以及列表末尾都将按价格升序排列。

您可以使用
UNION将两种选择组合起来。

SELECT * FROM `table` WHERE `special_price` IS NOT NULL ORDER BY `special_price` ASC,`price` ASC;
UNION ALL
SELECT * FROM `table` WHERE `special_price` IS NULL ORDER BY `price` ASC;
我不知道,从性能的角度来看,这是如何表现的,但据我所知,这就像两个简单的查询,从
UNION
得到的开销很小


次要更新:由于两个查询无法返回相同的记录,因此不需要默认行为
UNION DISTINCT
,我希望
UNION ALL
的性能稍微好一点。

您可以将两个选择与
UNION
结合起来

SELECT * FROM `table` WHERE `special_price` IS NOT NULL ORDER BY `special_price` ASC,`price` ASC;
UNION ALL
SELECT * FROM `table` WHERE `special_price` IS NULL ORDER BY `price` ASC;
我不知道,从性能的角度来看,这是如何表现的,但据我所知,这就像两个简单的查询,从
UNION
得到的开销很小

次要更新:由于两个查询无法返回相同的记录,因此不需要默认行为
UNION DISTINCT
,我希望
UNION ALL
的性能会稍微好一点。

试试看

SELECT * FROM table_name ORDER BY CASE special_price
        WHEN '0.00' THEN 1
        WHEN null THEN 3
        ELSE 2
    END
试一试


如果要对大量行进行排序,使用函数返回值对结果进行排序可能会非常慢,因为MySQL无法使用索引对这些值进行排序。那么,如何避免这种情况呢

如果某个项目必须处于“特殊”状态才能免费(从您提供的表格布局图像来看似乎是这样),您可以尝试:

SELECT *, special_price IS NULL AS not_special
FROM tablename
ORDER BY not_special ASC, special_price ASC, price ASC;
这会在结果中添加一个额外的列,如果该项处于特殊状态,则该列等于0,否则为1。然后,我们将所有“特殊”项目放在排序的顶部,并按特殊价格和价格升序排序


这将允许您避免
UNION
的开销,仍然使用索引进行排序操作,并避免在使用函数返回值对大量行进行排序时出现非常慢的查询。。。但只有当项目必须处于“特殊”状态才能免费时,使用函数返回值对结果进行排序会非常慢,因为MySQL无法使用索引对这些值进行排序。那么,如何避免这种情况呢

如果某个项目必须处于“特殊”状态才能免费(从您提供的表格布局图像来看似乎是这样),您可以尝试:

SELECT *, special_price IS NULL AS not_special
FROM tablename
ORDER BY not_special ASC, special_price ASC, price ASC;
这会在结果中添加一个额外的列,如果该项处于特殊状态,则该列等于0,否则为1。然后,我们将所有“特殊”项目放在排序的顶部,并按特殊价格和价格升序排序


这将允许您避免
UNION
的开销,仍然使用索引进行排序操作,并避免在使用函数返回值对大量行进行排序时出现非常慢的查询。。。但只有当一件物品必须处于“特殊”状态才能免费使用时。

插上电源,它才能正常工作!你介不介意解释一下,让我将来能学习和理解?非常感谢。难道不需要列吗?我的理解是MySQL不能使用索引对函数返回的值进行排序。如果有大量行要排序,那么这可能会非常慢。我很好奇是否有一种方法可以在没有
COALESCE()
的情况下执行此操作?@Drew将在
COALESCE
之后应用
限制,因此重要的数字将是数据库中有多少个(或者查询的其余部分确实返回了多少个)。但即使如此,我也不认为5000张唱片会很糟糕。如果它太长(~0.5秒+),你可以通过AJAX加载它,因为它听起来可能是一个web应用程序。如果我理解正确,
限制
不会影响这里查询的性能,因为MySQL需要创建完整的结果表,然后才能将其减少到所需的记录数。作为旁注:缓存结果:),因为它看起来并不是每分钟都会改变。插上它,它就能完美工作!你介不介意解释一下,让我将来能学习和理解?非常感谢。难道不需要列吗?我的理解是MySQL不能使用索引对函数返回的值进行排序。如果有大量行要排序,那么这可能会非常慢。我很好奇是否有一种方法可以在没有
COALESCE()
的情况下执行此操作?@Drew将在
COALESCE
之后应用
限制,因此重要的数字将是数据库中有多少个(或者查询的其余部分确实返回了多少个)。但即使如此,我也不认为5000张唱片会很糟糕。如果它太长(~0.5秒+),您可以通过AJAX加载它,因为它听起来像是一个web应用程序