SELECT查询,其中LIMIT是重复键的不同计数

时间:2019-07-12 12:00:59

标签: mysql sql

我在选择特定数量的数据时遇到问题。问题在于其中一个键具有相同的重复值。

--------------------
| id | name | key |
--------------------
| 1  | alfa |  a  |
| 2  | alfa |  b  |
| 3  | alfa |  c  |
| 4  | beal |  a  |
| 5  | beal |  b  |
| 6  | gala |  c  |
| 7  | gala |  d  |
| 8  | delt |  a  |
| 9  | ceta |  a  |
--------------------

在这种情况下,我想选择三个单独的名称。例如,我想将唯一名称限制为3个位置以获得此结果:

样品转储码:

SELECT * in Table
WHERE `name` LIKE '%al%' 
LIMIT BY DISTINCT
 `name`, 3

------ RESULT ------
| 1  | alfa |  a  |
| 2  | alfa |  b  |
| 3  | alfa |  c  |
| 4  | beal |  a  |
| 5  | beal |  b  |
| 6  | gala |  c  |
| 7  | gala |  d  |
--------------------

我会很高兴获得帮助。

2 个答案:

答案 0 :(得分:2)

没有窗口功能:

select *
from (
  select distinct name
  from mytable
  where `name` like '%al%' 
  order by name
  limit 3
) n
natural join mytable

db-fiddle

如果您不喜欢NATURAL JOIN,也可以使用

select t.*
from (
  select distinct name
  from mytable
  where `name` like '%al%' 
  order by name
  limit 3
) n
join mytable t on t.name = n.name

如果支持窗口功能,则可以使用DENSE_RANK()

with cte as (
  select *,
  dense_rank() over (order by name) as dr
  from mytable
  where `name` like '%al%'
)
  select id, name, `key`
  from cte
  where dr <= 3

db-fiddle

我更喜欢LIMIT 3子查询,因为它可以在找到三个不同的名称后停止索引扫描(取决于优化程序)。

答案 1 :(得分:0)

使用Window functions的MySQL 8.0解决方案如下:

SELECT 
  dt.id, dt.name, dt.`key` 
FROM 
(
  SELECT 
    ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) AS rn, 
    id, 
    name, 
    `key`
  FROM your_table_name 
  WHERE name LIKE '%al%'
) AS dt 
WHERE dt.rn <= 3 
ORDER BY dt.id 

说明:

  1. Derived table(子查询)中,确定特定名称(由id升序排列)的分区(组)中的Row_Number()。我们将只考虑符合%al%条件的名称。
  2. 现在,使用子查询结果仅SELECT行号最多为3的行(每个名称基本上限制为3行)。
  3. 顺便说一下,keyReserved Keyword in MySQL。您应该考虑将列重命名为其他名称;否则,您将需要使用反引号。

结果

| id  | name | key |
| --- | ---- | --- |
| 1   | alfa | a   |
| 2   | alfa | b   |
| 3   | alfa | c   |
| 4   | beal | a   |
| 5   | beal | b   |
| 6   | gala | c   |
| 7   | gala | d   |

View on DB Fiddle