MySql 使用联合时,查询不对记录排序

MySql query doesn't order records, when using union

我的 MySQL 数据库中有 3 个表。

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fullname` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `softs` (
  `Id` int(11) NOT NULL,
  `Title` varchar(50) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `plans` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `SoftId` int(11) NOT NULL,
  `Explain` varchar(500) NOT NULL,
  `Rating` int(11) NOT NULL,
  `Done` tinyint(4) NOT NULL,
  `NowIs` datetime NOT NULL,
  `DoneTime` datetime NOT NULL,
  `note` varchar(30) NOT NULL,
  `userid` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `SoftId` (`SoftId`),
  KEY `userid` (`userid`),
  CONSTRAINT `plans_ibfk_1` FOREIGN KEY (`SoftId`) REFERENCES `softs` (`Id`),
  CONSTRAINT `plans_ibfk_2` FOREIGN KEY (`userid`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

我想先检索未完成的记录并按 'rating' 列升序排列,然后是已完成的计划,按 'DoneTime' 列降序排列。 因此我在下面写了查询。

(SELECT a.id, b.title, a.`Explain`, a.Done, a.DoneTime, a.note, c.fullname, a.rating 
    FROM plans as a 
    inner join softs as b ON b.Id = a.SoftId 
    inner join users as c ON c.id = a.userid 
    where(a.done = 0) order by a.Rating asc)
union
(SELECT a.id, b.title, a.`Explain`, a.Done, a.DoneTime, a.note, c.fullname, a.rating 
    FROM plans as a 
    inner join softs as b ON b.Id = a.SoftId 
    inner join users as c ON c.id = a.userid 
    where(a.done = 1) 
    order by a.Donetime desc) ;

当我 运行 它们分开时,每个都工作正常,但“联合”记录未排序。

如何通过一次查询完成这项任务?

我什至没有看到这里需要联合查询,只需添加适当的 ORDER BY 子句:

SELECT a.id, b.title, a.`Explain`, a.Done, a.DoneTime, a.note, c.fullname, a.rating 
FROM plans AS a 
INNER JOIN softs AS b ON b.Id = a.SoftId 
INNER JOIN users AS c ON c.id = a.userid 
ORDER BY
    a.done,    -- undone records first, done second
    CASE WHEN a.done = 0 THEN a.rating ELSE -1*UNIX_TIMESTAMP(a.DoneTime) END;

ORDER BY 子句中的 CASE 表达式值得一些解释。在未完成记录的情况下,第二级排序使用等级升序。在 done 记录的情况下,我们按完成时间中的负秒数排序。这将在较早的时间之前对较晚完成的时间进行排序(即按 DoneTime“降序”)。