【问题标题】:How to combine these two sql statements如何组合这两条sql语句
【发布时间】:2013-08-02 11:56:39
【问题描述】:

我在 sql 方面不是很有经验,但通常可以通过构建基本查询,但这对我来说太复杂了,无法解决。

我有两个查询,每个查询分别给出我需要的结果,但是我需要将它们组合起来以获得我需要的最终结果。

在一个查询中,它获取特定学生的所有“分数”并返回平均值。在另一个查询中,我从表中删除最高和最低记录。

我想结合这些查询首先去除最高和最低分数,然后只返回剩余记录的平均分数。请帮助指导我使用正确的语法。

我的查询:


这将返回所有最高和最低分数:

SELECT *
FROM `scores`
WHERE `tot_score` = (
SELECT MAX( `tot_score` )
FROM `scores` )
OR `tot_score` = (
SELECT MIN( `tot_score` )
FROM `scores` ) 

这会返回平均分数:

SELECT `pres_id`, COUNT( `pres_id` ) , ROUND( AVG( `tot_score` ) , 2 ) , `username`, `name`, `pres_day`
FROM `scores`, `users`
WHERE `users.id_user` = `scores.pres_id`
GROUP BY `pres_id`

如何将这些结合起来得到我需要的结果?

【问题讨论】:

  • 结合显示一些示例数据和所需输出是什么意思?

标签: mysql sql


【解决方案1】:

我建议您在单个子查询中计算最小值和最大值。然后,您可以简单地使用 where 子句过滤您想要的行:

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id join
     (select s.pres_id, max(tot_score) as maxts, min(tot_score) as mints
      from scores s
      group by s.pres_id
     ) ssum
     on u.id_user = ssum.pres_id
where s.tot_score > ssum.mints and s.tot_score < ssum.maxts
GROUP BY s.`pres_id`;

我猜你想去掉每个学生的最高和最低分数。如果您只想省略 所有 个学生的最高和最低值,请使用以下代码:

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id cross join
     (select max(tot_score) as maxts, min(tot_score) as mints
      from scores s
     ) ssum
where s.tot_score > ssum.mints and s.tot_score < ssum.maxts
GROUP BY s.`pres_id`;

编辑:

修改以在学生只有一个分数时保留分数:

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id join
     (select s.pres_id, max(tot_score) as maxts, min(tot_score) as mints,
             count(*) as cnt
      from scores s
      group by s.pres_id
     ) ssum
     on u.id_user = ssum.pres_id
where (s.tot_score > ssum.mints and s.tot_score < ssum.maxts) or (cnt = 1)
GROUP BY s.`pres_id`;

【讨论】:

  • 嗨,戈登,感谢您的回复。我注意到您的语法有错误(交叉连接上的反引号)。查询运行没有错误,最初似乎返回了我需要的结果,但我需要检查一些记录,看看它是否给了我想要的结果......
  • 是的,没错。我想从每个学生的分数中去除最大和最小分数(每个实例),并返回每个学生剩余结果的平均值。当我尝试运行您的第一个查询时,它返回“#1052 - 字段列表中的列 'pres_id' 不明确错误”
  • @user1734104 。 . .它需要别名来指定它来自哪个表。
  • 谢谢 Gordon,你的第一个查询返回了正确的结果,虽然我后来想,“如果一个学生记录的所有分数都是相同的值怎么办”,我想这会返回一个平均分数零值,对吗?如果是这样,调整查询以留下一条记录作为结果有多容易?如果不是这么简单的编辑,我可能会发布另一个问题。
  • @user1734104 。 . .当学生的所有值都是最大值或最小值时,您需要决定要做什么。你可以问另一个问题,参考这个问题,并澄清这种情况的规则是什么。但是,我将做一个小改动,以在学生只有一个分数时保留这些值。
【解决方案2】:

您应该能够反转高/低分查询,然后将其用作现有平均查询的结果集:

SELECT `pres_id`, COUNT( `pres_id` ) , ROUND( AVG( `tot_score` ) , 2 ) , `username`, `name`, `pres_day`
FROM (
    SELECT `tot_score`
    FROM `scores`
    WHERE `tot_score` <> (
    SELECT MAX( `tot_score` )
    FROM `scores` )
    OR `tot_score` <> (
    SELECT MIN( `tot_score` )
    FROM `scores` ) 
) AS `scores`, `users`
WHERE `users.id_user` = `scores.pres_id`
GROUP BY `pres_id`

【讨论】:

  • 感谢您的建议。我运行了查询,但它返回了一个 #1054 - '字段列表' 中的未知列 'pres_id'。我还尝试将 SELECT 更改为“scores.pres_id”,但仍然返回相同的错误“未知列”。有什么想法吗?
  • @user1734104,然后只需更改内部查询以选择那些附加字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2021-03-15
  • 1970-01-01
  • 2023-03-14
  • 2013-02-24
相关资源
最近更新 更多