我有一组需要同时以多种方式订购的数据。
简化后,该表可以概括为:
我需要生成这些任务的列表,主要按“完成”排序,其次按“日期”排序,然后按“组”分组。
该小组是导致我这个问题的原因,我觉得用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)
即。如果组中的任务的日期早于单个任务,则应首先对整个组进行排序(假设对于组,您只能看到“顶部”任务,因此任务#3将在视觉上折叠。)
我已经尝试改变'ORDER BY'子句的顺序,但似乎任何组合都没有达到我所追求的目标 - 某些东西总是在错误的地方结束。
非常感谢任何帮助。
答案 0 :(得分:1)
所以你想按照小组中最早的日期排序,然后将整个小组保持在一起?
您可以在YourTable上使用聚合来获得每组的最低日期。然后,您可以主要在该最小日期排序,然后在其他字段上排序。
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
然后,您可以开始在该聚合中包含其他字段(如完整)。例如,此查询应从包含未完成任务和未完成的单个任务的组开始。之后,完成的任务和仅包含已完成任务的组。在组内,仍然应用排序,将未完成的任务放在上面完成的任务上,然后按日期对它们进行排序。正如您所看到的,只需对查询进行少量更改即可获得许多额外逻辑:
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
答案 1 :(得分:1)
如下:
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
对于每个群组记录,将其加入该群组中最早的记录,然后您可以按最早的群组日期(如果没有分组,那么只是日期)进行排序。