2016-04-21 2 views
0

У меня есть этот запрос, который работает очень хорошоПолучите максимум и минимум значений со всеми значениями и множественным, где положение

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. 

так я вообще я хочу получить новые обновленные записи pls max вверх и вниз.

если многие максимальные значения voteup одинаковы, то просто выберите тот, который уже мин votedown

Любое решение, что PLS?

Здесь my sqlfiddle example

Edit: ой извините я имел в виду идентификатор. Теперь хочу, чтобы мой вопрос ясен как enter image description here

+0

Ваш скрипт sql не имеет поля 'id', с которым вы используете в предложении GROUP BY в приведенном выше рабочем документе. –

+0

@JeffPuckettII edted, извините, что я имел в виду id :) –

+0

у вас все еще есть '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' не определены в том порядке, в котором вы их выбрали в последней части. И технически вы все еще не вычисляете max и min, просто извлекаете строки, в которых они находятся. – Uueerdo

+0

им не вычислять no, im fetching, я еще не пришел к правильному результату вашего ответа. –

+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 и минимум вниз голосования, если больше чем одна строка существует (в галстуке), она захватывает строку с самым последним/самым большим 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

Я называю это CRAZY, потому что это ... если я это делал. Я бы просто запустить 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) не дает один макс с меньшим количеством downvote, он должен давать id 41,42,43 –

+0

что-то странное со скрипкой, потому что я выполнил это заявление против моего локального db и получил ожидаемые результаты. –