Php 用于多维排序/分组的多个mysql ORDER BY

Php 用于多维排序/分组的多个mysql ORDER BY,php,mysql,codeigniter,Php,Mysql,Codeigniter,我有一组数据需要以多种方式同时排序 简化后,该表可概括为: 任务 身份证件 组int 日期 完成0/1 我需要生成这些任务的列表,主要按“完成”排序,其次按“日期”排序,然后按“组”分组 对我来说,这个群体是问题的根源,我有一种感觉,使用PHP可以更好地实现这一点,因为这可能不可能成为查询的一部分——欢迎提供关于实现这一点的最佳方法的提示,它当然不必是纯mysql 目前我正在使用: ORDER BY complete, group, date 这非常适用于“未分组”任务,所有未完成的0任务位于

我有一组数据需要以多种方式同时排序

简化后,该表可概括为:

任务 身份证件 组int 日期 完成0/1 我需要生成这些任务的列表,主要按“完成”排序,其次按“日期”排序,然后按“组”分组

对我来说,这个群体是问题的根源,我有一种感觉,使用PHP可以更好地实现这一点,因为这可能不可能成为查询的一部分——欢迎提供关于实现这一点的最佳方法的提示,它当然不必是纯mysql

目前我正在使用:

ORDER BY complete, group, date
这非常适用于“未分组”任务,所有未完成的0任务位于顶部,完成的1任务位于底部;按日期排序的每组完成/未完成任务

然而,一个组可能最终被聚在底部,在更广泛的上下文中,日期顺序是不正确的-由于任务的日期,该组本身没有被放置。下面是一个不需要的输出排序示例:

Task #2 - Group(false), Complete(0), date(2013-11-01)
Task #4 - Group(false), Complete(0), date(2013-12-01)
Task #5 - Group(1), Complete(0), date(2013-10-01)
Task #3 - Group(1), Complete(0), date(2013-12-01)
Task #1 - Group(false), Complete(1), date(2013-11-01)
如您所见,分组项目的日期排序不正确,排序发生在组内。任务5排在第三位,尽管它的日期最早

我想看到的输出如下:

Task #5 - Group(1), Complete(0), date(2013-10-01)
Task #3 - Group(1), Complete(0), date(2013-12-01)
Task #2 - Group(false), Complete(0), date(2013-11-01)
Task #4 - Group(false), Complete(0), date(2013-12-01)
Task #1 - Group(false), Complete(1), date(2013-11-01)
i、 e.如果一个组中的任务的日期早于单个任务,则应首先对整个组进行排序。想象一下,在一个组中,您只看到“最上面”的任务,因此任务3将在视觉上折叠

我试着改变“ORDERBY”子句的顺序,但似乎任何组合都不能达到我想要的效果——有些东西总是在错误的地方结束


非常感谢您的帮助。

那么您想按组中最早的日期排序,然后将整个组放在一起吗

您可以在表上使用聚合来获取每个组的最低日期。然后,您可以主要按该最小日期排序,然后按其他字段排序

select
  t.id,
  t.group,
  t.date,
  t.complete
from
  YourTable t
  left join
    (select
      m.group,
      min(m.date) as mindate
    from
      YourTable m) mt on mt.group = t.group
order by
  /* Coalesce for individual tasks, which don't have a mindate */
  coalesce(mt.mindate, t.date),
  t.group,
  t.complete,
  t.date
然后,您可以开始在聚合中包含其他字段,如Complete。例如,此查询应以包含未完成任务和未完成单个任务的组开始。然后是已完成的任务和仅包含已完成任务的组。在组内,仍然应用排序,将未完成的任务放在已完成的任务之上,然后按日期排序。如您所见,仅对查询进行一个小的更改,就有很多额外的逻辑:

select
  t.id,
  t.group,
  t.date,
  t.complete
from
  YourTable t
  left join
    (select
      m.group,
      min(m.date) as mindate,
      min(m.complete) as groupcomplete
    from
      YourTable m) mt on mt.group = t.group
order by
  coalesce(mt.groupcomplete, t.complete),
  coalesce(mt.mindate, t.date),
  t.group,
  t.complete,
  t.date

比如说:

SELECT t1.ID, t1.`Group`, t1.Complete, t1.Due 
FROM task t1
LEFT JOIN (
    SELECT Complete, 
        t.`Group`, 
        MIN(Due) AS MinDate 
    FROM task t
    GROUP BY Complete, t.`Group` ) t2 ON t1.complete = t2.complete AND t1.`Group`  = t2.`Group`     
ORDER BY t1.complete, IFNULL(t2.MinDate, t1.Due), `Group`, t1.Due 
对于每个组记录,将其连接到该组中最早的记录,然后您可以按最早的组日期排序,如果未分组,则仅按日期排序


请向我们展示您的完整查询。除了“ORDER BY”之外,这只是一个基本的select查询,带有与未提及或与问题相关的列相关的“where”。谁想到让“return”提交这些评论?气死人了。这看起来很积极!我只是想看看如何将其转换为CodeIgniter的活动记录语法,然后试一试。令人烦恼的是,我认为我明天才有机会看到这一点,所以我将进行更新,希望到时候能标记为正确答案!不幸的是,我正努力将这一点融入CI的活动记录语法中,还有一个问题需要解决,如果您有任何CI方面的经验,请随时查看!我不太了解CI的活动记录语法,但我想我仍然发现了您的错误。我已经提供了一个答案但除此之外,最好使用Toad或PHPMyAdmin之类的工具,以便在将查询迁移到CodeIgniter之前开发和测试查询。这样,您就可以验证错误是否确实存在于迁移过程中,或者某个用户向您提供的查询中;通常情况下,CI的语法比通过PHPMyAdmin检查要快-但是在这种情况下,这似乎不是真的:我认为你的猜测是正确的,但是仍然有一些小的语法问题,与你的答案无关。不幸的是,这只是给我产生语法错误:1064-你的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解第5行“group,MINdue AS MinDate FROM task GR”附近使用的正确语法。注意,我已将“date”更改为“due”,并且“task”是表的名称。我已将答案改为使用t。group而不仅仅是group-还必须将FROM表行更改为FROM表t。希望这足以克服这个错误。否则,试着在每一次提到“组”列的时候都加上勾号,我可以看到6。看起来是这样的,因为列组被解析为Group BY开头的Group。谢谢,这确实修复了该错误!新的一个:1582-对本机函数'ISNULL'的调用中的参数计数不正确-有什么想法吗?哇,是的,它的意思是IFNULL。我在这里使用的是sql server,它现在使用ISNULL-更新答案。刚刚修复了第8行complete拼写错误的拼写错误。获得增量
我个人担心我可能没有测试过这个,我想我确实认为这可以让查询正常工作——但不幸的是,它产生的结果与我在问题中不想要的示例完全相同。i、 e.结果是:任务按日期排序,然后在其他任务之后分组,日期无关,然后完成任务-它不会将组滑入日期范围中的适当位置。所以,它似乎除了按完成、分组、日期排序之外,什么都没有做