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
“降序”)。
我的 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
“降序”)。