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>";
}
MySQLMAX()
对字母数字值不起作用
如果您的表中没有太多行,那么可以获取所有数据并使用完整的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