获取最大值和最小值以及所有值和多个where子句

时间:2016-04-21 20:21:56

标签: mysql max

我有这个非常好的查询

  SELECT cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown 
  FROM chat_messages cm 
  WHERE TIMESTAMPDIFF(SECOND,cm.date_edited,'$now') < 10 GROUP BY cm.id

它为我提供了在不到10秒内编辑的条目。

但同时我也试图获得max(voteup)min(votedown)

但是不要影响第一个查询的第一个条目。我如何组合然后获得我需要的所有条目?

示例:

如果即时获得3个新更新条目。我想让他们获得3加上最多的投票和投票。

示例:

    id   edited  date_edited          voteup    votedown
    37      0      2016-03-05 22:13:03    5         0
    38      0      2016-04-02 11:15:00    3         7
    39      0      2016-03-05 22:10:06    10        6
    40      0      2016-03-20 21:40:06    5         0
    41      1      2016-04-20 22:28:59    5         0
    42      1      2016-03-20 21:59:15    0         20
    43      1      2016-04-21 22:20:25    8         0     <---- this new updated

我希望的结果是

    id   edited  date_edited         voteup  votedown  maxup  maxdown
    39      0      2016-03-05 22:10:06    10        6    10     NULL
    42      1      2016-03-20 21:59:15    0         20   NUll   20
    43      1      2016-04-21 22:20:25    8         0    NULL   NULL  

我的$now时间是2016-04-21 22:20:20

说明:

   -id 39 is having maxup vote i want get it

   -id 42  is having maxdown i want get it

   -id 43 is newly updated in that period of 10 seconds.

所以我想要获得新的更新条目请将最大值上下调整。

如果许多最大投票数值相同,那么只需选择一个投票最少的投票

该解决方案是什么?

此处 my sqlfiddle example

编辑:哦对不起我的意思是id。现在希望我的问题清楚如enter image description here

2 个答案:

答案 0 :(得分:2)

您需要使用UNION声明:

SELECT * FROM (
    select cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown 
        , voteup as maxup, null AS maxdown
    from chat_messages cm
    ORDER BY voteup DESC, votedown
    LIMIT 1
) a
UNION
SELECT * FROM (
    select cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown 
        , null as maxup, votedown AS maxdown
    from chat_messages cm
    ORDER BY votedown DESC, voteup
    LIMIT 1
) b
UNION
SELECT * FROM (
  SELECT cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown 
        , null as maxup, null AS maxdown
  from chat_messages cm
  WHERE TIMESTAMPDIFF(SECOND,cm.date_edited,'2016-04-21 22:20:20') < 10
) c

请注意,我使用的是'2016-04-21 22:20:20',但您需要将$now替换为

答案 1 :(得分:1)

您可以使用用户定义的变量来跟踪您的最大值,然后外部查询符合您规则的行。

SELECT id,edited,date_edited,voteup,votedown,
       IF(voteup=@maxvoteup,voteup,NULL) as maxvoteup,
       IF(votedown=@maxvotedown,votedown,NULL) as maxvotedown
FROM (SELECT cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown,
       @maxvoteup := GREATEST(@maxvoteup,cm.voteup) as maxvoteup,
       @maxvotedown := GREATEST(@maxvotedown,cm.votedown) as maxvotedown
      FROM chat_messages cm,(SELECT @maxvoteup:=0,@maxvotedown:=0)initial
     )T
WHERE TIMESTAMPDIFF(SECOND,date_edited,'2016-04-21 22:20:25') < 10
   OR voteup = @maxvoteup
   OR votedown = @maxvotedown
ORDER BY id ASC

sqlfiddle

这里的另一个查询更加疯狂......但是它有效......

对于maxupvote行,它会找到具有maxupvote和最小向下投票的行,如果存在多于1行(处于平局状态),它将获取具有最新/最大ID的行。 对于maxdownvote行,它会找到具有maxdownvote和最小投票权的行, 如果存在多于一行(并列),它将获取具有最新/最大ID的行。

SELECT id,edited,date_edited,voteup,votedown,
       IF(voteup=@maxvoteup,voteup,NULL) as maxvoteup,
       IF(votedown=@maxvotedown,votedown,NULL) as maxvotedown
FROM (SELECT cm.id ,cm.edited,cm.date_edited,cm.voteup,cm.votedown,
       @minvotedown :=
            (CASE WHEN cm.voteup > @maxvoteup OR (cm.voteup = @maxvoteup AND cm.votedown < @minvotedown)
                  THEN cm.votedown
                  ELSE @minvotedown
            END),
       @minvoteup :=
            (CASE WHEN cm.votedown > @maxvotedown OR (cm.votedown = @maxvotedown AND cm.voteup < @minvoteup)
                  THEN cm.voteup
                  ELSE @minvoteup
            END),
       @maxvoteup := GREATEST(@maxvoteup,cm.voteup) as maxvoteup,
       @maxvotedown := GREATEST(@maxvotedown,cm.votedown) as maxvotedown,
       @maxvoteupid :=
             (CASE WHEN cm.voteup = @maxvoteup AND cm.votedown = @minvotedown 
              THEN cm.id
              ELSE @maxvoteupid
              END),
       @maxvotedownid :=
             (CASE WHEN cm.votedown = @maxvotedown AND cm.voteup = @minvoteup
              THEN cm.id
              ELSE @maxvotedownid
              END)
      FROM chat_messages cm,(SELECT @maxvoteup:=0,@maxvotedown:=0,@minvoteup:=0,@minvotedown:=0,@maxvoteupid:=0,@maxvotedownid:=0)initial
      ORDER BY cm.id ASC
     )T
WHERE TIMESTAMPDIFF(SECOND,date_edited,'2016-04-21 22:20:25') < 10
   OR id = @maxvoteupid
   OR id = @maxvotedownid
ORDER BY id ASC;

sqlfiddle

我称之为疯狂,因为它是......如果我这样做的话。我只会运行3个单独的查询

1个查询返回order by upvote DESC, downvote ASC, id DESC限制1

的一行

1个查询返回order by downvote DESC, upvote ASC, id DESC限制1

的一行

1个查询返回最后10秒内的一行order by id DESC 这样,维护起来就容易得多。