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

时间:2016-04-14 09:51:16

标签: php mysql sorting group-by

我有下表:

store_items

foreach (var item in this.ListBox1.Items)
{
    list2.Add(Conversions.ToString(item));
}

正如您所看到的 item_no 包含数字和文字,在排序时我知道它很痛苦。但是,我试图测试这个PHP代码:

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

我想要的只是输出分组在一起的cat和sub列表,其中每个列表将在其旁边列出最新/最高//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

3 个答案:

答案 0 :(得分:1)

此处的主要问题是MAX(item_no)MAX(id)cat值的sub不对应。另一个问题是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()函数来确定每个item_no对的正确最大cat,sub值:

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

希望这会对你有所帮助。

答案 1 :(得分:0)

MySQL MAX()无法处理字母数字值。

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

如果你的桌子太大,你应该考虑增加另一个领域,比如Gary Hayes说。您可以使用自动增量ID。

答案 2 :(得分: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并将其余部分抛弃。