SQL选择最大值和平均值

huangapple go评论82阅读模式
英文:

SQL Select Max and Average

问题

以下是您请求的部分翻译:

环境是MySQL8。我有一个名为`bird`的表格。

鸟与`Check`相关联

每个`check`可以有多个`weights``measurements`

`weights`

`measurements`

对于给定的`bird`,我应该如何返回一个包含以下结果集:

我尝试自己编写查询并且做到了:

但如何嵌套和平均`measurements``length`的结果,它们可能与不同的`checks`相关联,这是我卡住的地方,因此关于答案SQL如何工作的解释将会有所帮助

请注意,我只翻译了您提供的代码和问题的相关部分。如果您需要进一步的帮助或解释,请随时提出。

英文:

Environment is MySQL8. I have a table bird

+----+--------+--------+
| id |  name  |  sex   |
+----+--------+--------+
| 1  | bob    | male   |
| 2  | mary   | female |
| 3  | jono   | male   |
+----+--------+--------+ 

Bird is associated to Check

+----+-------------+---------+
| id | check_date  | bird_id |
+----+-------------+---------+
| 1  | 2023-06-01  |       2 |
| 2  | 2023-07-01  |       2 |
| 3  | 2023-08-01  |       2 |
+----+-------------+---------+

And each check can have several weights and measurements:

weights

+----+---------+----------+
| id | weight  | check_id | 
+----+---------+----------+
|  1 |    3.3  |        2 |
|  2 |    3.45 |        2 |
|  3 |    3.8  |        2 |
|  4 |    4.5  |        1 |
|  5 |    4.51 |        1 |
+----+---------+----------+

measurements

+----+---------+----------+
| id | measur  | check_id |
+----+---------+----------+
|  1 |    95.2 |        1 |
|  2 |    97.4 |        1 |
|  3 |    96.4 |        1 |
|  4 |    99.1 |        3 |
|  5 |    98.1 |        3 |
+----+---------+----------+

For a given bird how would I return a result set containing

+---------+-----------+--------------+--------------------------+-------------------------+--------------------+-------------------+
| bird.id | bird.name | newest check | date newest measurements | avg newest measurements | date newest weight | avg newest weight |
+---------+-----------+--------------+--------------------------+-------------------------+--------------------+-------------------+
|       2 | mary      | 2023-08-01   | 2023-08-01               |                    98.6 | 2023-07-01         |              3.52 |
+---------+-----------+--------------+--------------------------+-------------------------+--------------------+-------------------+

I have attempted to write the query myself and got as far as :

SELECT bird.id, bird.name, MAX(check.catch_date), weight
FROM bird
LEFT JOIN check ON bird.id=check.bird_id
LEFT JOIN measurements ON measurements.check_id=check.id
WHERE bird.id=2
GROUP BY id, weight;

But the way to nest and average the result of measurements and length which could be associated to different checks is where I am stuck so narrative on how the answer SQL works would be helpful.

答案1

得分: 2

我建议不要使用 Keywords and Reserved Words ,比如 check ,因为你必须始终使用反引号。

关于这个问题(也许有一个简单的解决方案)。

但是嵌套和平均测量结果和长度,可能与不同的检查相关联,这是我卡住的地方。

可以通过连接和使用存在来检索最大的 check_id 来实现。

select MAX(c.check_date) as date_newest_weight,
       ROUND(AVG(w.weight),2) as avg_newest_weight,
       c.bird_id
from  `check` c  
inner join weights w on c.id = (select max(w.check_id) from weights w where exists (select id from `check` c where c.bird_id = 2))
where c.bird_id = 2 
group by c.bird_id;

结果

date_newest_weight   avg_newest_weight   bird_id
2023-07-01           3.91               2

最终查询

select b.id as bird_id,
       b.name as bird_name,
       max(c.check_date) as newest_check,
       date_newest_measurements,
       avg_newest_measurements,
       date_newest_weight,
       avg_newest_weight
from bird b 
inner join `check` c on b.id=c.bird_id
inner join ( select  MAX(c.check_date) as date_newest_measurements,
                     ROUND(AVG(m.measur),2) as avg_newest_measurements,
                     c.bird_id
             from  `check` c  
             inner join measurements m on c.id =(select max(m.check_id) from measurements m where exists (select id from `check` c where c.bird_id = 2)) 
             where c.bird_id = 2 
             group by c.bird_id
           ) as max_meas  on max_meas.bird_id=c.bird_id
inner join (
            select MAX(c.check_date) as date_newest_weight,
                   ROUND(AVG(w.weight),2) as avg_newest_weight,
                   c.bird_id
            from  `check` c  
            inner join weights w on c.id = (select max(w.check_id) from weights w where exists (select id from `check` c where c.bird_id = 2))
            where c.bird_id = 2 
            group by c.bird_id
           )  as max_weig on max_weig.bird_id=c.bird_id
group by bird_id,
         bird_name,
         date_newest_measurements,
         avg_newest_measurements,
         date_newest_weight,
         avg_newest_weight;

结果

bird_id   bird_name   newest_check   date_newest_measurements   avg_newest_measurements   date_newest_weight   avg_newest_weight
2         mary        2023-08-01    2023-08-01                98.60                    2023-07-01          3.52

这里可以看到示例。

英文:

I recommend not using Keywords and Reserved Words such as check because you have to always use backticks.

Regarding the question (maybe there is a simple solution).

> But the way to nest and average the result of measurements and length
> which could be associated to different checks is where I am stuck

This can be done by join and the help of exist to retrieve the max check_id

select MAX(c.check_date) as date_newest_weight,
       ROUND(AVG(w.weight),2) as avg_newest_weight,
       c.bird_id
from  `check` c  
inner join weights w on c.id = (select max(w.check_id) from weights w where exists (select id from `check` c where c.bird_id = 2))
where c.bird_id = 2 
group by c.bird_id;

Result

date_newest_weight	avg_newest_weight	bird_id
      2023-07-01	       3.91         	2

Final query

select b.id as bird_id,
       b.name as bird_name,
       max(c.check_date) as newest_check,
       date_newest_measurements,
       avg_newest_measurements,
       date_newest_weight,
       avg_newest_weight
from bird b 
inner join `check` c on b.id=c.bird_id
inner join ( select  MAX(c.check_date) as date_newest_measurements,
                     ROUND(AVG(m.measur),2) as avg_newest_measurements,
                     c.bird_id
             from  `check` c  
             inner join measurements m on c.id =(select max(m.check_id) from measurements m where exists (select id from `check` c where c.bird_id = 2)) 
             where c.bird_id = 2 
             group by c.bird_id
           ) as max_meas  on max_meas.bird_id=c.bird_id
inner join (
            select MAX(c.check_date) as date_newest_weight,
                   ROUND(AVG(w.weight),2) as avg_newest_weight,
                   c.bird_id
            from  `check` c  
            inner join weights w on c.id = (select max(w.check_id) from weights w where exists (select id from `check` c where c.bird_id = 2))
            where c.bird_id = 2 
            group by c.bird_id
           )  as max_weig on max_weig.bird_id=c.bird_id
group by bird_id,
         bird_name,
         date_newest_measurements,
         avg_newest_measurements,
         date_newest_weight,
         avg_newest_weight;

Result

bird_id bird_name   newest_check    date_newest_measurements    avg_newest_measurements date_newest_weight  avg_newest_weight
  2      mary         2023-08-01         2023-08-01                    98.60                 2023-07-01             3.52

See example here

huangapple
  • 本文由 发表于 2023年8月10日 18:37:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76874938.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定