2016-04-21 36 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

有一些奇怪的小提琴,因爲我對我的本地數據庫運行了這個聲明並獲得了預期的結果。 –