【问题标题】:ORDER by multiple queries in MySql通过 MySql 中的多个查询进行排序
【发布时间】:2021-09-25 06:03:43
【问题描述】:

我正在尝试构建一个聊天列表页面,其中最新发送/接收的联系人显示在一个表格的顶部。为此,我有一张表smshistory 存储发送/接收的短信,其中一个是公司电话,另一个是客户电话号码

CREATE TABLE IF NOT EXISTS `smshistory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fromnumber` varchar(20) NOT NULL,
  `tonumber` varchar(20) NOT NULL,
  `sms` varchar(20) NOT NULL,
  `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

--
-- Dumping data for table `smshistory`
--

INSERT INTO `smshistory` (`id`, `fromnumber`, `tonumber`, `sms`, `added`) VALUES
(1, 'companynum', 'client1num', 'Hello', '2021-07-16 12:28:23'),
(2, 'companynum', 'client2num', 'Hello', '2021-07-16 12:28:23'),
(3, 'companynum', 'client3num', 'Hello', '2021-07-16 12:28:23'),
(4, 'client1num', 'companynum', 'Hi', '2021-07-16 12:28:23'),
(5, 'companynum', 'client1num', 'Hello', '2021-07-16 12:28:23'),
(6, 'client1num', 'companynum', 'Hi', '2021-07-16 12:28:23'),
(7, 'client2num', 'companynum', 'Hi', '2021-07-16 12:28:23'),
(8, 'companynum', 'client2num', 'Hello', '2021-07-16 12:28:23'),
(9, 'client3num', 'companynum', 'Hi', '2021-07-16 12:28:23');

因为第一条消息总是来自公司编号,所以我显示DISTINCT 列表:

SELECT DISTINCT (`tonumber`) FROM `smshistory` WHERE `fromnumber` = $companynum

这给了我这样的清单:

client1num
client2num
client3num

要求:

我需要以added DESC 列的顺序显示DISTINCT,如果客户的号码在fromnumbertonumber 中,它应该显示在顶部。所以,根据我的表格,结果应该是:

client3num
client2num
client1num

小提琴位于http://sqlfiddle.com/#!9/4256d1d/1

你知道如何实现吗?

【问题讨论】:

  • 观察一下:DISTINCT 不是函数
  • 我不明白排序规则。如果是因为行中有数字“3”、“2”和“1”,那么数据库设计可能需要快速重新考虑!
  • @JSBach 是的,数据库设计非常糟糕,但由于它是我的任务,所以我无法更改它,需要相应地提供结果。
  • 所以问题是'如何根据这些字符串中包含的数字对字符串集合进行排序?'

标签: mysql group-by max case inner-join


【解决方案1】:

在回答“如何根据这些字符串中包含的数字对非规范化的字符串集合(遵循非常受限的模式)进行排序?”的问题时,这是一种方法......

DROP TABLE IF EXISTS x;

CREATE TABLE x
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,bad_string VARCHAR(20) NOT NULL
);

INSERT INTO x VALUES (11,'client2num'),(17,'client3num'),(21,'client1num');

SELECT REPLACE(REPLACE(bad_string,'client',''),'num','') p FROM x;
+---+
| p |
+---+
| 2 |
| 3 |
| 1 |
+---+

...可以改写如下:

SELECT * FROM x ORDER BY REPLACE(REPLACE(bad_string,'client',''),'num','') DESC;
+----+------------+
| id | bad_string |
+----+------------+
| 17 | client3num |
| 11 | client2num |
| 21 | client1num |
+----+------------+

【讨论】:

  • 感谢您的努力,但您弄错了,不是根据数字进行排序。我们有 2 个值和 2 列,其中一个值相同,但其他值可以更改。两个值都可以在一条记录的两列中的任何一列中,并且可以有多个具有相同变化值的记录。我们必须按照顺序获得不同的变化值列表,以便我们可以在顶部获得变化值,该值位于最新记录中,而与列无关。
  • 嗯,在之前的 cmets 中,您非常表示的,所以我将把这个留给其他人。
【解决方案2】:

对于在fromnumbertonumber 中包含$companynum 的每一行,您必须使用CASE 表达式提取客户号码并使用GROUP BY 删除重复项。
最后按照added的最大值对结果进行排序:

SELECT CASE WHEN fromnumber = $companynum THEN tonumber ELSE fromnumber END client_num
FROM smshistory
WHERE $companynum IN (fromnumber, tonumber)
GROUP BY client_num
ORDER BY MAX(added) DESC

【讨论】:

  • 非常感谢。它解决了。再问一个问题,如果有像 message 这样的字段来存储发送和接收的短信正文,我们将如何显示发送或接收的最后一条消息以显示在聊天头上?
【解决方案3】:

在回答您的问题时,您可以使用以下查询:

SELECT distinct client_num from ( 
SELECT CASE WHEN fromnumber = 'companynum' THEN tonumber 
ELSE fromnumber END client_num 
FROM smshistory ORDER BY id DESC ) as a

【讨论】:

  • 谢谢,但请您检查一下我的小提琴sqlfiddle.com/#!9/35fad3/13。根据那个小提琴,答案应该是client2num,client1num,client3num。我的问题不是总是像 client3num、client2num、client1num 那样对它进行排序,但谁甚至在 tonumber 或 fromnumber 列中有最新条目。
  • 我认为下面的查询可以满足您的要求,是 forpas 提供的查询,稍加修改 select distinct client_num from (SELECT CASE WHEN fromnumber = 'companynum' THEN tonumber ELSE fromnumber END client_num FROM smshistory ORDER BY id DESC ) 作为一个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 2021-11-24
  • 1970-01-01
  • 2013-10-21
相关资源
最近更新 更多