【问题标题】:MySql query doesn't order records, when using union使用联合时,MySql 查询不排序记录
【发布时间】:2021-08-03 14:12:20
【问题描述】:

我的 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;

我想首先检索未完成的记录,并按“评级”列按升序排列,然后是已完成的计划,按“完成时间”列按降序排列。 因此我写了下面的查询。

(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) ;

当我单独运行它们时,每个都可以正常工作,但“联合”记录没有排序。

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

【问题讨论】:

  • 只需在 SELECT 中添加一个标志,然后按该标志有条件地排序。
  • @Rory McCrossan 我不懂“标志”。能提供简单的吗?
  • 我不知道你为什么在那条评论中给我加了标签?我只是从问题中删除了“jquery”标签,因为它与您的 SQL 问题无关,因为它是一个客户端 JS 框架。
  • 即a.id AS id,并按id排序
  • 我不小心做到了。我的意思是“查询”

标签: mysql union


【解决方案1】:

我什至看不到这里需要联合查询,只需添加适当的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“降序”)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多