2016-04-21 35 views
0

我有这个疑问,其工作原理非常好的所有值和相处最大值和最小值多个where子句

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. 

,所以我一般我想获得新的更新条目,请上下调整大小。

如果许多最大voteup值相同,则只需选择一个已分钟votedown

任何解决这一PLS?

这里my sqlfiddle example

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

+0

您的sql小提琴没有'id'字段,您在上面的工作语句的'GROUP BY'子句中使用了它。 –

+0

@JeffPuckettII编辑,对不起,我的意思是编号:) –

+0

你在上面的select语句中仍然有'cm.userid'; –

回答

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

如果'chat_messages'中的字段没有按照您在最后一部分中选择它们的顺序定义,那么会爆炸或有奇怪的行为。从技术上讲,你仍然没有计算最大和最小值,只是提取它们所在的行。 – Uueerdo

+0

即时通讯不计算不,不会提取,我没有从你的答案中得出正确的结果。 –

+0

在哪里检查并将NULL或值? –

1

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

SELECT id,edited,date_edited,voteup,votedown, 
     IF([email protected],voteup,NULL) as maxvoteup, 
     IF([email protected],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

这里的另一个查询更加CRAZY..but它的工作原理..

为maxupvote行,它会发现,有maxupvote和最低首投票,如果有更多的排比1行存在(在领带上)它会抓住具有最新/最大ID的行。 maxdownvote行,它会发现有maxdownvote和最小的投票, 如果超过1行存在(在领带),它会抢最新/最大的ID行。

SELECT id,edited,date_edited,voteup,votedown, 
     IF([email protected],voteup,NULL) as maxvoteup, 
     IF([email protected],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 这种方式更容易维护。

+0

我相当肯定,查询将有非常不可预知的结果。我是会话变量的忠实粉丝,但他们的声誉很差,因为它们在跨子句中使用时行为不可预测。 – Uueerdo

+0

看起来[小提琴](http://www.sqlfiddle.com/#!9/25004/1)不会给一个最大值减少倒数,它应该给编号41,42,43 –

+0

有一些奇怪的小提琴,因为我对我的本地数据库运行了这个声明并获得了预期的结果。 –