2016-04-14 48 views
1

我有叫如下表:PHP在按降序排序工作不正常

store_items

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 

正如你可以看到ITEM_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>"; 
} 

所有我想要的是组合在一起的猫和子的输出列表中为它的每一个会列到它的最新/最item_no ...如下:

期待输出:

cat sub item_no 
lady sport 1l1550bk 
men shoe 2m1600rd 
baby shoe 3l1000bk 

回答

0

的MySQL MAX()不上的字母数字值的工作。

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

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

+0

所以我认为它不可能做到这一点哦,我现在要尝试编辑表格结构。 –

+0

@AliHamra你可以做到。看到我的答案。如果你想改变你的表格结构,可能只需添加一个“created_at”列。 –

0

如果您没有在GROUP BY中使用它或对其应用聚合函数,那么SELECT item_no没有意义。你会随机得到一个是item_no的伸手范围值。您可以改为SELECT cat, sub, GROUP_CONCAT(item_no) as item_nos

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”改成“item_no”。 GROUP_CONCAT将按照该顺序为您提供逗号分隔的item_no列表。 SUBSTRING_INDEX函数然后只让你输入第一个item_no,然后丢掉它。

+0

感谢您的回复,我的意思是基于预期的产出,我需要找出与其类别相关的最新项目编号,因为每次收到新产品时项目编号始终递增。我试过使用你的查询,但我得到'mysqli_error()期望1个参数是资源...'。我会再次检查什么是错的 –

+0

我在我的查询中修复了几个错误。 1是我错过了FROM子句。我强烈建议你在PHP中试用之前直接在MySQL中尝试查询(例如,在phpMyAdmin中),以便清楚地看到任何MySQL错误。你的mysqli错误是因为我的查询错误,导致返回值为布尔FALSE而不是结果资源。 –

1

这里的主要问题是,MAX(item_no)MAX(id)对应,对于特定的catsub值不对应。另一个问题是,item_no本身是字母数字,并不能自然地确定哪一个是最大的。因为你可以先定义你自己的函数(因为MySQL不提供这样的),它可以让你item_no值转换为纯数字的字符串的情况下(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 $$ 

然后你可以使用这个功能STRIP_NON_DIGIT()确定每个cat,sub对适当的最大item_no值:

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 

希望这会帮助你。

+0

感谢您的回复,我将会理解并测试您所写的内容。我会通知你结果:) ..再次感谢 –