PHP按降序排序未按预期工作

PHP按降序排序未按预期工作,php,mysql,sorting,group-by,Php,Mysql,Sorting,Group By,我的下表名为: 储存物品 id item_no cat sub 1 1l500bk lady sport 2 1l1550bk lady sport 3 2m1600rd men shoe 4 2m1599rd men shoe 5 2m1589rd men shoe 6 3l900bk baby shoe 7 3l1000bk baby shoe 正如您所看到的,项\u no包含数字和文本,当涉及排序时,我知道这很痛苦。但是,我尝试

我的下表名为:

储存物品

id item_no   cat   sub
1  1l500bk   lady  sport
2  1l1550bk  lady  sport
3  2m1600rd  men   shoe
4  2m1599rd  men   shoe
5  2m1589rd  men   shoe
6  3l900bk   baby  shoe
7  3l1000bk  baby  shoe
正如您所看到的,项\u no包含数字和文本,当涉及排序时,我知道这很痛苦。但是,我尝试测试了以下PHP代码:

//Table of results
$query = "SELECT * from store_items GROUP by cat,sub ORDER by cat,sub,item_no Desc";
$result = mysql_query($query);
if(!$result){
    mysqli_error();
}

while($row=mysql_fetch_assoc($result)){
    echo "<tr><td align=center>{$row['cat']}</td><td align=center>{$row['sub']}</td><td align=center>";

   echo ucfirst($row['item_no']);

   echo "</td></tr>";
}
MySQL
MAX()
对字母数字值不起作用

如果您的表中没有太多行,那么可以获取所有数据并使用完整的PHP完成这项工作


如果您的表太大,您应该考虑添加另一个字段,如Gary Hayes所说。您可以使用自动增量ID。

如果您不是在GROUP BY中使用项目或对其应用聚合函数,则选择项目\u no实际上没有意义。您将随机获得一个是reach行中的项目\无值。您可以
选择cat、sub、GROUP\u CONCAT(项目编号)作为项目编号

SELECT cat, sub, SUBSTRING_INDEX(GROUP_CONCAT(item_no ORDER BY id DESC),',',1) as newest_item_no
FROM store_items
GROUP BY cat, sub
ORDER BY cat,sub

编辑:我不确定你所说的最新/最高商品编号是什么意思,但我上面的查询假设最高ID是最新的商品。在GROUP_CONCAT内部,如果您希望按“id”排序,则可以将“id”更改为“item_no”
GROUP_CONCAT
将按顺序为您提供以逗号分隔的项目编号列表。然后,子字符串索引函数仅获取丢失的第一个项目编号,并将其余项目丢弃。

这里的主要问题是
MAX(项目编号)
MAX(id)
不对应于特定的
cat
sub
值。另一个问题是
item_no
本身是字母数字的,无法自然确定哪一个是最大值。在这种情况下,您可以首先定义自己的函数(因为MySQL不提供这样的函数),该函数允许您将
项号
值转换为纯数字字符串(1l1550bk->11550):

自定义SQL函数:

DROP FUNCTION IF EXISTS STRIP_NON_DIGIT;
DELIMITER $$
CREATE FUNCTION STRIP_NON_DIGIT(input VARCHAR(255))
   RETURNS VARCHAR(255)
BEGIN
   DECLARE output   VARCHAR(255) DEFAULT '';
   DECLARE iterator INT          DEFAULT 1;
   DECLARE count INT DEFAULT 0;
   WHILE iterator < (LENGTH(input) + 1) AND count < 10 DO
      IF SUBSTRING(input, iterator, 1) IN ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
         SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
         SET COUNT=COUNT+1;
      END IF;
      SET iterator = iterator + 1;
   END WHILE;
   RETURN output;
END
$$
DELIMITER $$
这将为您提供所需的输出:

+------+-------+----------+
| cat  | sub   | item_no  |
+------+-------+----------+
| baby | shoe  | 3l1000bk |
| lady | sport | 1l1550bk |
| men  | shoe  | 2m1600rd |
+------+-------+----------+
3 rows in set

希望这能对您有所帮助。

所以我认为这是不可能的,哦,好吧,我现在尝试编辑表结构。@AliHamra您可以做到。看看我的答案。如果您想更改表结构,也许只需添加一个“created_at”列。感谢您的回复,我的意思是基于预期输出,我需要找出与其类别相关的最新商品编号,因为每次收到新产品时,商品编号总是递增。我已尝试使用您的查询,但我得到了
mysqli\u error()期望1个参数为resource…
。我将再次检查出了什么问题。我修复了查询中的几个错误。1是我遗漏了从句。我强烈建议您在PHP中尝试之前,直接在MySQL中尝试查询(例如在phpMyAdmin中),这样您就可以清楚地看到任何MySQL错误。您的mysqli错误是因为我的查询错误,它导致返回值为Boolean FALSE而不是result resource。感谢您的回复,我将理解并测试您编写的内容。我会把结果告诉你:)。。再次感谢
SELECT
    s.cat,
    s.sub,
    s.item_no
FROM
    store_items s,
    (
        SELECT MAX(CAST(STRIP_NON_DIGIT(item_no) AS UNSIGNED)) as numeric_item, cat, sub 
        FROM store_items 
        GROUP BY cat, sub
    ) t
WHERE
    CAST(STRIP_NON_DIGIT(s.item_no) AS UNSIGNED) = t.numeric_item
    AND s.cat = t.cat
    AND s.sub = t.sub;
+------+-------+----------+
| cat  | sub   | item_no  |
+------+-------+----------+
| baby | shoe  | 3l1000bk |
| lady | sport | 1l1550bk |
| men  | shoe  | 2m1600rd |
+------+-------+----------+
3 rows in set