如何在where子句中为每个名称最多获取两个条目[重复]
Posted
技术标签:
【中文标题】如何在where子句中为每个名称最多获取两个条目[重复]【英文标题】:How to get at most two entries for each name in the where clause [duplicate] 【发布时间】: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 排除在外的? 【参考方案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 < 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
过滤这些数据
【讨论】:
【参考方案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 排序)以上是关于如何在where子句中为每个名称最多获取两个条目[重复]的主要内容,如果未能解决你的问题,请参考以下文章