来自两个表的SQL查询,按两个表列对结果进行排序


SQL query from two tables ordering results by both tables columns

我有两个表用于登记外出电话。

第一个表是人员。方案为:

-----------------------------------
id | fname | lname | phone_number |
-----------------------------------
1  | John  | Black | 132333312    |
2  | Marry | White | 172777441    |
-----------------------------------

被称为的第二个表调用。方案为:

----------------------------------------------------------------------
id | scr_phone | dst_phone | dst_public_id | date      | notes       |
----------------------------------------------------------------------
1  | 555       | 132333312 | 1             | 1.12.2013 | chit-chat   |
2  | 555       | 172777441 | 2             | 1.12.2013 | serios talk |
3  | 555       | 172777441 | 2             | 2.12.2013 | conversation|
----------------------------------------------------------------------

我不是按字母顺序,而是按通话频率为用户显示手机列表。因此,无论谁从本地电话555打电话,都会在顶部看到他/她打电话更频繁的人。以下是我用于它的MySQL查询:

SELECT p.fname, p.lname, c.notes, COUNT(c.dst_public_id) AS amount
FROM people p
JOIN calls c ON c.dst_public_id = p.id
WHERE phones != ''
GROUP BY p.id
ORDER BY amount DESC, p.lname ASC

结果,我把电话号码2排在电话列表的首位,把电话号码1排在第二位(我计算每个公众有多少电话,然后按这个数量订购)。以下是查询结果:

--------------------------------
fname | lname | notes | amount |
--------------------------------
Marry | White |       |  2     |
John  | Black |       |  1     |
--------------------------------

这一切都很好。但我总是想展示最后一次和那个人谈话时的最后一句话。我可能可以为每个请求最后一条记录并从中获取数据的人创建一个完全分离的MySQL查询,类似于:

SELECT notes FROM calls WHERE dst_public_id = 2 ORDER BY date DESC LIMIT 1

然后在我的PHP脚本中添加第一个查询的结果,但是有没有办法用一个查询来完成呢?

您可以使用以下MySQL技巧,使用group_concat()substring_index():获得最后一条注释

SELECT p.fname, p.lname, c.notes, COUNT(c.dst_public_id) AS amount,
       substring_index(group_concat(notes order by id desc separator '^'), '^', 1) as last_notes
FROM people p JOIN
     calls c
     ON c.dst_public_id = p.id
WHERE phones != ''
GROUP BY p.id
ORDER BY amount DESC, p.lname ASC;

为了实现这一点,您需要一个永远不会出现在注释中的分隔符。为此,我选择了'^'

你能试试这个吗?我没有测试过,因为我没有SQL在我面前,但你应该明白。

SELECT tbl.notes, tbl.amount, p.fname, p.lname
FROM people p
join
(
select t.dst_public_id, c1.notes, t.cnt as amount
from calls c1 join 
   (
      SELECT c2.dst_public_id, count(c2.id) as cnt, max(c2.id) as id
      FROM 
      calls c2
      group by c2.dst_public_id
   ) t on c1.id = t.id
) tbl on p.id = tbl.dst_public_id
WHERE p.phones != ''
GROUP BY p.id
ORDER BY tbl.amount DESC, p.lname ASC