SQL查询以获取特定父项的子项的平均值

时间:2017-11-01 19:23:28

标签: mysql sql database

我不确定问题标题。

让我们解释一下我的问题。

我有两张桌子1.奶牛和2.儿童

CREATE TABLE Cows (
cow_id int,
Name varchar(255));

CREATE TABLE Children (
child_id int,
cow_id int,
weight double,
time time,
fr_score double);

我将它们与左连接

组合在一起
select 
    cow.cow_id
    , cow.Name
    , child.child_id
    , Child.DOB
FROM(
    select cow_id
        , Name
    From cows
) as cow
left join (
    select child_id
        , cow_id
        , weight
        , time
        , fr_score
    From Children
) as child
on child.cow_id = cows.cow_id
order by cow.cow_id, child.child_id

我得到的结果是这......但是......

cow_id   child_id    weight       time      fr_score
------   --------    ------     --------    --------
 601       6011        78       05:00:15       2.5
 601       6012        58       05:00:15       2.6
 601       6013        88       07:12:50       0.0
 601       6014        77       09:10:50       4.5
 602       6021        98       13:12:53       1.6
 602       6022        85       15:00:12       1.8
 602       6023        68       17:22:35       2.9
 603       6031        73       20:22:12       3.8
 603       6032        72       21:04:52       2.6
 604       6041        78       23:43:45       4.1

但我想要的是得到这个结果(平均来自特定母牛的孩子的重量,这将是每一头牛和它的孩子)。 " XX / XXX"表示平均值

cow_id   child_id    weight       time      fr_score
------   --------    ------     --------    --------
 601       6011        78       05:00:15       2.5
 601       6012        58       05:00:15       2.6
 601       6013        88       07:12:50       0.0
 601       6014        77       09:10:50       4.5
           avg-        XX                      XXX
 602       6021        98       13:12:53       1.6
 602       6022        85       15:00:12       1.8
 602       6023        68       17:22:35       2.9
           avg-        XX                      XXX
 603       6031        73       20:22:12       3.8
 603       6032        72       21:04:52       2.6
           avg-        XX                      XXX
 604       6041        78       23:43:45       4.1

4 个答案:

答案 0 :(得分:3)

所有人'在这里做的是在包含平均数的一组数据中联合。在外部查询中包装,以便我们可以按照您想要的方式进行排序,并添加一个列zorder来控制排序,以确保平均值出现在子项之后

  SELECT cow_id
     , Name
     , child_id
     , weight
     , time
     , fr_Score
FROM (SELECT cow.cow_id
           , cow.Name
           , child.child_id
           , child.weight
           , child.time
           , child.fr_Score
           , 0 zorder
      FROM cows as cow
      LEFT JOIN Children as child
        on child.cow_id = cow.cow_id
      UNION ALL
     SELECT cow_ID
           , NULL
           , NULL
           , avg(weight) 
           , NULL
           , avg(fr_Score) afs
           , 1 zorder 
      FROM children 
      GROUP BY cow_id) C
ORDER BY cow_id, zorder, child_id

注意:这确实包括子行上的父cow_ID w / average我们可以找到一种在需要时省略该数据的方法;但这通常是在UI层完成的。

正如bamar指出的那样,也可以使用汇总来完成:http://sqlfiddle.com/#!9/885370/2/1

Select * from (
SELECT cow.cow_id
           , cow.Name
           , child.child_id
           , avg(child.weight)
           , child.time
           , avg(child.fr_Score)
      FROM cows as cow
      LEFT JOIN Children as child
        on child.cow_id = cow.cow_id
Group by cow_ID, child_Id with rollup) z
WHERE Cow_ID is not null

答案 1 :(得分:0)

由于您要使用聚合函数,您必须记住,您需要使用group by函数来指定SQL如何对结果进行分组。 然后,因为你带来了“child_id”,你将永远不会通过cow_id带来平均值,因为SQL会尝试为每个孩子做出平均值。 所以,如果你想通过奶牛带来平均体重,你应该尝试类似的事情:

SELECT COW.NAME,
       AVG(CHILD.WEIGHT) AVERAGE
FROM CHILD
INNER JOIN COW ON CHILD.COW_ID=COW.COW_ID
GROUP BY COW.NAME

如果我理解你想要的东西,就像它一样

答案 2 :(得分:0)

根据你的需要你可以做这样的事情;虽然,不是100%内联你的东西,它可能适合你所需要的......

WITH
Merged
AS
(
    SELECT  cow.[cow_id]
            , child.[child_id]
            , child.[weight]
            , child.[time]
            , child.[fr_score]
    FROM Cows As cow
    LEFT JOIN (
                SELECT [child_id]
                      , [cow_id]
                      , [weight]
                      , [time]
                      , [fr_score]
                FROM Children
             ) AS child
        ON child.cow_id = cow.cow_id
)
,
Average
AS
(
SELECT [cow_id]
       ,AVG([weight]) AS Average_Weight
       ,AVG([fr_score]) AS Average_fr_score
FROM Merged
GROUP BY cow_id
)
SELECT M.[cow_id]
       ,[child_id]
       ,[weight]
       ,[time]
       ,[fr_score] 
       ,[Average_Weight]
       ,[Average_fr_score]
FROM Merged AS M
JOIN Average AS A
    ON M.[cow_id] = A.[cow_id]

答案 3 :(得分:0)

我认为您需要了解ROLLUP修饰符首先,您可以阅读有关RoLLUP的基本文档ROLLUP modifier

然后你可以关注@xQbert第二次查询

Select * from (
SELECT cow.cow_id
           , cow.Name
           , child.child_id
           , avg(child.weight)
           , child.time
           , avg(child.fr_Score)
      FROM cows as cow
      LEFT JOIN Children as child
        on child.cow_id = cow.cow_id
Group by cow_ID, child_Id with rollup) z
WHERE Cow_ID is not null