使用GROUP BY和ORDER BY进行mysql查询的奇怪结果

时间:2014-05-30 14:00:23

标签: mysql sql group-by sql-order-by

只是想知道是否有人能在这里发现任何明显错误的事情。我在MySQL中使用SELECT会得到奇怪的结果。我看不出查询有什么问题,所以我想知道是否有一些数据丢掉了,但数据确实看起来没问题。所以我猜我的sql有点不对劲!

我有两张桌子,CITY和WEATHER:

CITY:
  CITY_ID    INT(3)
  CITY_NAME  VARCHAR(100)

WEATHER:
  CITY_ID   INT(3)
  SDATE     DATETIME
  TEMP      INT(3)
  RAIN      INT(3)

CITY表非常小;每个定义城市一行。

WEATHER表有很多行;它对每个城市都有预测(每天几次)。还有历史预测,所以有数据可以追溯到几个月。

我希望每行看到每个城市的摘要。 我想要所有城市信息一个月,然后是上个月等。 在每个月内,我希望结果按温度(降序)排序,然后降雨(降序)。

所以,我的查询:

 SELECT     a.city_name                   as CITY
          , DATE_FORMAT(b.sdate, '%M %Y') as MONTH
          , ROUND(avg(b.temp))            as AVG_TEMP_C
          , SUM(b.rain)                   as RAIN
 FROM       CITY a , WEATHER b
 WHERE      a.city_id = b.city_id
 GROUP BY   a.city_name , DATE_FORMAT(b.sdate, '%M %Y')
 ORDER BY   sdate desc,  ROUND(avg(b.temp)) desc , SUM(b.rain) desc;

我期望的结果:

CITY         MONTH  TEMP   RAIN
ISTANBUL     June   20     0
MUNICH       June   15     9
PARIS        June   15     7
MILAN        June   14     8
ISTANBUL     May    19     22
etc.

我得到的结果:

CITY         MONTH  TEMP   RAIN
MUNICH       June   15     9
MILAN        June   14     8
ISTANBUL     June   20     0
PARIS        June   15     7
ISTANBUL     May    19     22
etc.

就像我说的那样,数据看起来好了,所以我想我错过了所有格式,联接,组和订单中的一些东西..

3 个答案:

答案 0 :(得分:3)

这是您的查询,具有显式连接和更明智的表别名(表缩写而不是任意字母):

 SELECT     c.city_name                   as CITY,
            DATE_FORMAT(w.sdate, '%M %Y') as MONTH,
            ROUND(avg(w.temp))            as AVG_TEMP_C,
            SUM(w.rain)                   as RAIN,
 FROM       CITY a JOIN
            WEATHER w
            ON c.city_id = w.city_id
 GROUP BY   c.city_name , DATE_FORMAT(w.sdate, '%M %Y')
 ORDER BY   sdate desc,  ROUND(avg(w.temp)) desc , SUM(w.rain) desc;

order by中的第一列是sdate。但是,这不包含在您的group by子句中。因此,MySQL为每个城市选择了来自不确定行的值sdate(在其他数据库中,这会产生错误)。

相反,请将order by更改为使用月份和年份:

 ORDER BY   year(sdate) desc,  month(sdate) desc, ROUND(avg(w.temp)) desc , SUM(w.rain) desc;

答案 1 :(得分:1)

您按sdate排序,该日期位于聚合结果表中,但不是聚合函数的主题。因此,mysql接受任何与其他条件匹配的sdate值(可能是第一个?)并按此值排序。

答案 2 :(得分:0)

我很想回收每个城市/月的最大日期,然后在ORDER BY中使用它(格式化为CCYYMM格式)以正确的顺序获取它们。

这样的事情: -

SELECT a.city_name as CITY , 
        DATE_FORMAT(b.sdate, '%M %Y') as MONTH , 
        MAX(b.sdate) AS max_date,
        ROUND(avg(b.temp)) as AVG_TEMP_C , 
        SUM(b.rain) as RAIN 
FROM CITY a 
INNER JOIN WEATHER b 
ON a.city_id = b.city_id 
GROUP BY a.city_name , MONTH
ORDER BY DATE_FORMAT(max_date, '%Y%m') desc, AVG_TEMP_C desc , RAIN desc;

或略有不同: -

SELECT a.city_name as CITY , 
        DATE_FORMAT(b.sdate, '%M %Y') as MONTH , 
        MAX(b.sdate) AS max_date,
        ROUND(avg(b.temp)) as AVG_TEMP_C , 
        SUM(b.rain) as RAIN 
FROM CITY a 
INNER JOIN WEATHER b 
ON a.city_id = b.city_id 
GROUP BY a.city_name , MONTH
ORDER BY YEAR(max_date) desc, MONTH(max_date) desc, AVG_TEMP_C desc , RAIN desc;