【问题标题】:How to get at most two entries for each name in the where clause [duplicate]如何在where子句中为每个名称最多获取两个条目[重复]
【发布时间】:2016-09-27 04:05:18
【问题描述】:

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

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

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

我想要的输出是:

id
1
5
4
8

为了清楚起见,LIMIT 将针对每个变量返回 {limit} 行。

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

【问题讨论】:

  • 所以您的要求是:每个名称最多需要两个条目?
  • 我是如何决定将 6 排除在外的?

标签: mysql


【解决方案1】:

这是查询:

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 &lt; 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 &lt; 2 过滤这些数据

【讨论】:

    【解决方案2】:

    为什么你不这样使用union

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

    注意( 括号。

    【讨论】:

    • 最后需要Order by name,id
    • 您还需要在WHERE IN (.....) 子句中为每个用户选择一个查询,然后将它们联合起来。
    • 不,您不需要Order By 子句,因为您已经按照您想要的顺序排列了名称。 @ringø
    • 如果您有很多 name 想要 union 他们,那么您可以构建一个 procedure 或使用您使用的语言构建查询,例如 PHP
    • 好吧,在这种情况下,您至少需要在每个查询中使用 order by id,否则 ID 的顺序可能不同(OP 建议每个名称的 ID 按 ASC 排序)
    猜你喜欢
    • 2018-11-01
    • 1970-01-01
    • 2015-02-14
    • 2015-08-17
    • 2015-12-18
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2015-09-29
    相关资源
    最近更新 更多