使用垂直限制mysql获取表数据

时间:2015-02-23 14:35:21

标签: mysql

我需要帮助使用mysql查询使用垂直限制来获取数据

这是我的示例表

 -----------------
| id | pid | text |
 -----------------
|  1 |   1 | abc  |
|  2 |   2 | def  |
|  3 |   3 | ghi  |
|  4 |   1 | jkl  |
|  5 |   2 | mno  |
|  6 |   4 | pqr  |
|  8 |   2 |  vw  |
|  9 |   1 | xyz  |
| 10 |   3 | stu  |
| 11 |   5 | xyz  |
| 12 |   6 | stu  |
 -----------------

如何在一个查询中的每个pid中获取限制2数据的数据

例如表格我想得到的结果如下所示

 -----------------
| id | pid | text |
 -----------------
|  1 |   1 | abc  |
|  4 |   1 | jkl  |
|  2 |   2 | def  |
|  5 |   2 | mno  |
|  3 |   3 | ghi  |
| 10 |   3 | stu  |
|  6 |   4 | pqr  |
| 11 |   5 | xyz  |
| 12 |   6 | stu  |
 -----------------
我能这样做吗? 我尝试探索找到查询但未找到

感谢

3 个答案:

答案 0 :(得分:2)

有几种方法可以解决这个问题。一种方法使用子查询:

select e.*
from example e
where 2 >= (select count(*)
            from example e2
            where e2.pid = e.pid and e2.id <= e.id
           );

说明:子查询是相关子查询。它计算的每个id的行数小于同一行id的给定行pid。也就是说,它正在计算行的等级。 2 >=只是获取前两个值的一种方式。

答案 1 :(得分:1)

我不能在对Gordon Linoff的回答中写出这么多人物,所以我会在这里写下来。

我将尝试解释为什么Gordon Linoff的解决方案有效,以及它的工作原理。

我认为亚历克斯的问题是&#34;如果我有一个供应商的表和一个有联系人的表,每个联系人都属于供应商。因此,供应商可以拥有多个联系人,但每个联系人只能属于一个供应商。我想要一个返回联系人的查询,但每个供应商有两个联系人的限制。因此,我们可以为一个供应商列出零联系人,但为另一个供应商列出两个联系人,但不得超过两个。&#34;

以下是 Gordon Linoff 的解决方案:

select e.*
from example e
where 2 >= (select count(*)
            from example e2
            where e2.pid = e.pid and e2.id <= e.id
           );

如果我们首先跳过整个&#34;其中&#34; -clause,那么我们将返回每个联系人。现在我们需要检查这些联系人中的每个人,以确保我们每个供应商最多只能获得两个。

否于where子句。我们需要做的是确保只选择具有相同pid的两个(供应商ID)。因此,对于每个要检查的联系人,我们检查存在哪些属于同一供应商的其他联系人(具有相同的pid)以及具有较低或相等ID(联系人ID)作为我们当前正在检查的联系人。就是这样。

因为如果我们有三个联系人(比如id 1,4,9)包含同一个供应商(pid = 22),我们会计算具有相同pid的联系人数量(这意味着ID为1的联系人, 4和9因为所有三个都有22作为pid)。然后我们还检查联系人是否具有较低或相同的ID,然后返回计数。因此,当检查id 1时,计数将为1,因为只有他自己具有相同的pid和更低或相同的id,然后当检查id 4时我们内部&#34;选择&#34; -statement返回2因为id 1和id 4具有相同的pid和id小于或等于4.并且外部select语句中的where子句读取&#34; 2&gt; = 2&#34;。但是对于与id 9的联系,所有三个都被返回,因为所有三个都具有相同的pid并且id低于或等于9.并且&#34; 2&gt; = 3&#34;将为false,因此不会返回与id 9的联系。

我认为这可能是错误的方式留下一个重要的评论,但我认为其他人可能对戈登解决方案的工作原理感兴趣。

答案 2 :(得分:0)

SET @num := 0, @pid:= '';

SELECT t.id, t.pid, t.text 
      @num := if(@pid = t.pid, @num + 1, 1) AS row_number,
      @pid := t.pid AS dummy
FROM (
   SELECT * from table_name
   ORDER BY pid, id
) as t
GROUP BY t.id,t.pid, t.text
HAVING row_number <= 2
ORDER BY t.id, t.pid;