如何在where子句中为每个名称获取最多两个条目

时间:2016-05-29 06:12:13

标签: mysql

我想要完成的是选择具有限制的多个值。

SELECT id FROM table WHERE name IN ('Tom', 'Tommy') LIMIT 2

我理解这个查询不会按需运行,但它只是一个例子。 我无法完全了解情况

我想要的输出是:

id
1
5
4
8

为了说清楚,LIMIT将返回{limit}行PER变量。

LIMIT 3将每

返回3行
id
1
5
6
4
8

表:

id, name
1, Tom
2, Jeff
3, Jason
4, Tommy
5, Tom
6, Tom
7, Jeff
8, Tommy

2 个答案:

答案 0 :(得分:3)

以下是查询:

SELECT 
t.id,
t.name
FROM 
(
    SELECT 
    id,
    `name`,
    IF(@prevName = `name`, @nameRank := @nameRank + 1, @nameRank := 0) rank,
    @prevName := `name`
    FROM your_table, (SELECT @prevName := NULL, @nameRank := 0) var
    WHERE `name` IN ('Tom','Tommy')
    ORDER BY `name`,id
) t
WHERE t.rank < 2
ORDER BY t.id;

注意:您需要在此处设置限制WHERE t.rank < LIMIT

SQL FIDDLE DEMO

对您的示例数据运行上述查询,您将获得如下输出:

| id |  name |
|----|-------|
|  1 |   Tom |
|  4 | Tommy |
|  5 |   Tom |
|  8 | Tommy |

<强>解释

1)首先按升序name对数据进行排序

    SELECT 
     id,
     `name`
    FROM your_table
    WHERE `name` IN ('Tom','Tommy')
    ORDER BY `name`

<强>结果:

id  name
1   Tom
5   Tom
6   Tom
4   Tommy
8   Tommy

2) @prevName变量将跟踪之前是否已显示该名称。

3) @nameRank变量将为每个名称指定一个等级编号。如果当前名称已经是一个,那么它将为其分配一个递增的数字。 (如卷数)。

4)在上述两个变量的帮助下,中间表如下所示:

id  name   rank
1   Tom     0 (seen first time so rank = 0)
5   Tom     1 (seen second time so rank = rank + 1 ; rank = 1)
6   Tom     2 (seen third time so rank = 2)
4   Tommy   0 (seen first time so rank = 0)
8   Tommy   1 (seen second time so rank = 1)

5)由于每个名称最多需要两个条目,因此您需要根据rank < 2

过滤这些数据

答案 1 :(得分:0)

为什么你不这样使用union

(SELECT id FROM table WHERE name like 'Tom' LIMIT 2)
UNION
(SELECT id FROM table WHERE name like 'Tommy' LIMIT 2)

小心(括号。