【问题标题】:Get a limited subquery result from a query that's already limited MYSQL从已经受限的 MYSQL 查询中获取受限的子查询结果
【发布时间】:2019-05-16 23:33:15
【问题描述】:

我知道问题名称有点令人困惑,但我想做的是(如果可能的话)以下内容:在以下 MYSQL 查询中,我可以从前 15 人中获取所有电话号码,我需要的是使用此查询,如果此人的电话号码超过 3 个,则只返回前 3 个。

SELECT distinct(pp.PhoneNumber)
FROM person p
INNER JOIN personPhone pp ON p.personId = pp.personId
WHERE !ISNULL(pp.PhoneNumber)           
GROUP  BY p.PersonId, pp.PhoneNumber 
ORDER BY p.personId ASC LIMIT 0,15;

我尝试在distinct 语句内对SELECT 进行子查询,但没有任何成功

编辑:对不起,我忘了添加我正在使用的 MySQL 版本,它是 5.7.24

【问题讨论】:

  • 什么 MySQL 版本?窗口函数使这种查询更容易(MySQL-8.0/MariaDB-10.2+)
  • 为了便于阅读,我会使用WHERE pp.PhoneNumber IS NOT NULL
  • 请指定 MySQL 版本:8.x 还是 5.x?
  • DISTINCT 不是函数,GROUP BY 用于聚合。
  • 你如何定义“前三个”? SQL 表表示 无序 集。

标签: mysql sql subquery limit


【解决方案1】:

你没有说你有什么版本的 MySQL。如果你有 MySQL 8.x,你可以这样做:

select *
from (
  select
    personId, PhoneNumber, 
    row_number() over(partition by personId order by PhoneNumber) as rn
  from (
    SELECT distinct p.personId, pp.PhoneNumber
    FROM person p
    INNER JOIN personPhone pp ON p.personId = pp.personId
  ) x
) y
where rn <= 3

【讨论】:

    【解决方案2】:

    另一种方法是使用 GROUP_CONCAT 获取每个人的所有电话号码,然后使用 SUBSTRING_INDEX 确保您最多只能获取 3 个电话号码。

    SELECT p.PersonId ID, SUBSTRING_INDEX(GROUP_CONCAT(DISTINCT(pp.PhoneNumber)), ',', 3) Phone
    FROM person p
    INNER JOIN personPhone pp ON p.PersonId = pp.PersonId
    WHERE pp.PhoneNumber IS NOT NULL        
    GROUP  BY p.PersonId
    ORDER BY p.PersonId ASC LIMIT 15;
    

    【讨论】:

      【解决方案3】:

      您的查询未获取前 15 个人的所有电话号码。它有 15 个电话号码,可能少于 15 人。

      要限制为 15 人,请使用子查询。然后你可以限制每人三个数字:

      SELECT distinct(pp.PhoneNumber)
      FROM (SELECT p.*
            FROM person p
            ORDER BY p.personId
            LIMIT 15
           ) p15 INNER JOIN
           personPhone pp
           ON p.personId = pp.personId
      WHERE pp.PhoneNumber IS NOT NULL AND
            pp.PhoneNumber <= COALESCE( (SELECT pp2.PhoneNumber
                                         FROM personPhone pp2 
                                         WHERE pp2.PersonId = pp.PersonId
                                         ORDER BY pp2.PhoneNumber
                                         OFFSET 2 LIMIT 1
                                        ), pp.PhoneNumber)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多