选择max Mysql的位置

时间:2017-06-01 22:34:12

标签: mysql max sql-order-by where

求助请将sql选择到数据库。有这样的数据。

我的表是:

id  news_id  season  seria   date_update
---|------|---------|-----|--------------------
1  | 4    | 1       | 7   | 2017-04-14 16:38:10
2  | 4    | 1       | 7   | 2017-04-14 17:38:10
5  | 4    | 1       | 7   | 2017-04-14 16:38:10
3  | 4    | 1       | 7   | 2017-04-14 16:38:10
4  | 4    | 1       | 7   | 2017-04-14 16:38:10
6  | 4    | 1       | 7   | 2017-04-14 16:38:10
7  | 4    | 1       | 7   | 2017-04-14 16:38:10
8  | 1    | 1       | 25  | 2017-04-23 18:42:00

需要按最大季节和序列号和日期对所有单元格进行分组,并按date_update DESC排序。

结果我需要下一行

id  news_id  season  seria   date_update
---|------|---------|-----|--------------------
8  | 1    | 1       | 25  | 2017-04-23 18:42:00
2  | 4    | 1       | 7   | 2017-04-14 17:38:10

因为这一行有最高的季节,并且每个news_id有seria和date_update。即我需要选择具有最高季节的数据,按照news_id分组的seria和date_update以及按date_update DESC排序

我试过了,但数据并不总是正确的,并且它并不总是出于某种原因覆盖所有符合条件的细胞。

SELECT serial.* 
FROM serial as serial 
INNER JOIN (SELECT id, MAX(season) AS maxseason, MAX(seria) AS maxseria FROM serial GROUP BY news_id) as one_serial 
ON serial.id = one_serial.id 
WHERE serial.season = one_serial.maxseason AND serial.seria = one_serial.maxseria 
ORDER BY serial.date_update 

请帮忙。感谢。

2 个答案:

答案 0 :(得分:1)

规范尚不清楚。

但我们确实知道 GROUP BY news_id 子句会将公共值为news_id的所有行合并为一行。 (其他数据库会因此语法引发错误;如果我们在ONLY_FULL_GROUP_BY中包含sql_mode,我们可能会让MySQL抛出类似的错误。)

我的建议是从查询末尾删除 GROUP BY news_id 子句。

但这只是猜测。一点也不清楚你想要达到的目标。

修改

 SELECT t.* 
   FROM ( 
          SELECT r.news_id
               , r.season
               , r.seria
               , MAX(r.date_update) AS max_date_update
            FROM ( 
                   SELECT p.news_id
                        , p.season
                        , MAX(p.seria) AS max_seria
                     FROM ( 
                            SELECT n.news_id
                                 , MAX(n.season) AS max_season
                              FROM serial n 
                             GROUP BY n.news_id
                          ) o
                     JOIN serial p
                       ON p.news_id = o.news_id
                      AND p.season  = o.max_season
                 ) q
            JOIN serial r
              ON r.news_id = q.news_id
             AND r.season  = q.season
             AND r.seria   = q.max_seria
         ) s
    JOIN serial t      
      ON t.news_id     = s.news_id
     AND t.season      = s.season
     AND t.seria       = s.seria
     AND t.date_update = s.max_date_update
   GROUP BY t.news_id
   ORDER BY t.news_id 

或者,使用MySQL用户定义变量的另一种方法......

 SELECT s.id
      , s.season
      , s.seria
      , s.date_update 
   FROM ( 
          SELECT IF(q.news_id = @p_news_id,0,1) AS is_max
               , q.id
               , @p_news_id := q.news_id AS news_id
               , q.season
               , q.seria
               , q.date_update
            FROM ( SELECT @p_news_id := NULL ) r
           CROSS
            JOIN serial q
           ORDER
              BY q.news_id     DESC
               , q.season      DESC
               , q.seria       DESC
               , q.date_update DESC
        ) s
  WHERE s.is_max
  ORDER BY s.news_id

答案 1 :(得分:0)

子查询选择每season的最大seria和最大news_idnews_id存在多少与我们不知道的最大season和最大seria相匹配的记录。它可以是一,二,千或零。

因此,对于联接,您将获得每news_id个未知数量的记录。然后按news_id分组。这会为每个news_id获取一个结果行。那你怎么能选择serial.**表示行中的所有列,但是对于news_id可能有多行时,哪一行?在这种情况下,MySQL通常会随意选取值(通常都来自同一行,但即使这样也无法保证)。因此,您最终会得到date_update订购的随机行。

这没有多大意义。所以问题是:你真正想要实现什么?也许我的解释就足够了,你现在可以自己修复你的问题了。