为每个外键返回单行的查询

时间:2014-10-15 20:34:20

标签: mysql

我有一张例程表。在此表中,我有“等级”列(非强制性)和“日期”列。此外,我有很多天和一系列的用户ID。我需要一个查询,返回最后一个具有值的例程!= null为“grade”列和datediff(current_date,date)> = number_of_days为数组中的每个id并平均所有这些值。

e.g。

today = 2014/10/15

number_of_days = 10

ids(1,3)

子程序

id  | type | date       | grade | user_id
1   | 1    | 2014-10-10 | 3     | 1
2   | 1    | 2014-10-04 | 3     | 1
3   | 1    | 2014-10-01 | 3     | 1
4   | 1    | 2014-09-24 | 2     | 1
5   | 1    | 2014-10-10 | 2     | 2
6   | 1    | 2014-10-04 | 3     | 2
7   | 1    | 2014-10-01 | 3     | 2
8   | 1    | 2014-09-24 | 1     | 2
9   | 1    | 2014-10-10 | 1     | 3
10  | 1    | 2014-10-04 | 1     | 3
11  | 1    | 2014-10-01 | 1     | 3
12  | 1    | 2014-09-24 | 1     | 3

在这种情况下,我的查询将返回行ID#2的“等级”和#10

之间的平均值

1 个答案:

答案 0 :(得分:1)

我认为你是说要考虑在成绩列中具有非空值的行,在当前日期的给定天数内的日期,以及给定的一组user_id中的一个。在这些行中,对于每个user_id,您要选择具有最新日期的行,并计算这些行的成绩列的平均值。

我假设您不能拥有任何两行具有相同的user_id和date,两者都具有非空成绩,否则您想要提出的问题没有明确定义的答案。

沿着这些方向的查询应该可以解决问题:

SELECT AVG(r.grade) AS average_grade
  FROM 
    (SELECT user_id, MAX(date) AS date
      FROM routines
      WHERE grade IS NOT NULL
        AND DATEDIFF(CURDATE(), date) >= 10
        AND user_id IN (1,3)
      GROUP BY user_id) AS md
    JOIN routines r
      ON r.user_id = md.user_id AND r.date = md.date

请注意,原则上您需要在内部和外部查询上都有grade IS NOT NULL条件才能选择要平均的正确行,但实际上AVG()会忽略空值,因此您不需要实际上必须过滤掉外部查询中的额外行。