从MySQL视图中的每个父记录中获取子表中的N个记录

时间:2013-04-14 04:01:40

标签: mysql views mysql-5.5

我试着在SO中找到这个问题的答案,但找不到任何答案。任何链接都会有很大的帮助。

我有一个父表和一个子表,父表和子表之间有一对多的关系。子表包含大约100万条记录,我想在每个父记录的子表中创建一个包含前10条记录的视图。 示例 -

Parent_Table - Fields -- ID, Name
ID       Name
----     -----
1        A
2        B
3        C

Child_Table - Fields -- ID, ParentID, Date, Data
ID  ParentID  Date    Data
--------------------------
1     1        04/10   A1
2     1        04/11   A2
3     1        04/11   A3
4     1        04/12   A4
5     1        04/12   A5
6     2        04/10   B1
7     2        04/11   B2
8     2        04/12   B3
9     2        04/12   B4
10    2        04/13   B5
11    2        04/13   B6

现在,我想为按日期排序的每个父记录创建一个包含前4条记录的视图。

预期输出

ID  ParentID  Date    Data
--------------------------
1     1        04/10   A1
2     1        04/11   A2
3     1        04/11   A3
4     1        04/12   A4
6     2        04/10   B1
7     2        04/11   B2
8     2        04/12   B3
9     2        04/12   B4

我们将不胜感激为解决方案提供任何链接或指南。提前谢谢!

如果您需要任何澄清,请发表评论。

2 个答案:

答案 0 :(得分:1)

我在计算机上尝试过这个,并根据您的要求使用您自己的数据进行显示。我改变了一些字段名称,虽然像Child的Child到ChildID,Date到ChildDate,Data to ChildData。这是:

SELECT * FROM 
(SELECT ParentID, ChildID, ChildDate, ChildData, @ChildRank:= CASE WHEN @Parent <> ParentID THEN 1 ELSE @ChildRank+1 END as ChildRanking, @Parent := ParentID as Parent FROM 
(SELECT @ChildRank:=0) CR, (SELECT @Parent:=1) P, (SELECT * FROM Child_Table ORDER BY
ParentID, ChildID) MainTable) AllTable WHERE ChildRanking <=4;

我只使用子表,但无论如何,如果你愿意,你可以使用Parent_Table INNER JOIN。

一点解释:

1)ChildRank将从Rank 0开始(即SELECT @ChildRank:0),但由于@ ChildRank + 1,它将从Rank 1开始

2)当新的ParentID(即@ Parent&lt;&gt; ParentID)立即从Rank 1开始。

3)AllTable是所有内容的别名,因此您现在可以引用ChildRanking字段。

如果您不想显示ChildRanking字段,则必须指定要显示的字段。

答案 1 :(得分:1)

如果您需要创建VIEW,可以使用以下内容:

CREATE VIEW First_Four AS
SELECT c1.*
FROM
  Child_Table c1 LEFT JOIN Child_Table c2
  ON c1.ParentID = c2.ParentID
     AND (STR_TO_DATE(c1.`date`, '%m/%Y')>STR_TO_DATE(c2.`date`, '%m/%Y')
          OR (STR_TO_DATE(c1.`date`, '%m/%Y')=STR_TO_DATE(c2.`date`, '%m/%Y')
              AND c1.ID>c2.ID)
         ) 
GROUP BY
  c1.ID, c1.ParentID, c1.`Date`, c1.Data
HAVING
  COUNT(c2.ID)<4

我将字段数据视为VARCHAR列,因此我们需要使用STR_TO_DATE,如果不是,我们可以直接将c1。date与c2。date进行比较。

请参阅小提琴here