2013-12-17 1 views
3

РЕЖИМА это значение, которое происходит в самый раз в данных, может быть один режим или МНОГО РЕЖИМЫЕсть более простой способ найти режим (S) некоторых значений в MySQL

вот некоторые значения в двух таблицах (sqlFiddle)

create table t100(id int auto_increment primary key, value int); 
create table t200(id int auto_increment primary key, value int); 

insert into t100(value) values (1), 
           (2),(2),(2), 
           (3),(3), 
           (4); 
insert into t200(value) values (1), 
           (2),(2),(2), 
           (3),(3), 
           (4),(4),(4); 

прямо сейчас, чтобы получить режим (S) возвращается как разделенный запятыми список, я запускаю ниже запрос для таблицы t100

 SELECT GROUP_CONCAT(value) as modes,occurs 
    FROM 
     (SELECT value,occurs FROM 
      (SELECT value,count(*) as occurs 
      FROM 
      T100 
      GROUP BY value)T1, 
     (SELECT max(occurs) as maxoccurs FROM 
      (SELECT value,count(*) as occurs 
      FROM 
      T100 
      GROUP BY value)T2 
     )T3 
     WHERE T1.occurs = T3.maxoccurs)T4 
     GROUP BY occurs; 

и бела ow для таблицы t200 (тот же запрос, что и с именем таблицы, изменен). В этом примере у меня есть 2 таблицы, потому что показано, что он работает для случаев, когда есть 1 MODE и где есть несколько MODES.

 SELECT GROUP_CONCAT(value) as modes,occurs 
    FROM 
     (SELECT value,occurs FROM 
      (SELECT value,count(*) as occurs 
      FROM 
      T200 
      GROUP BY value)T1, 
     (SELECT max(occurs) as maxoccurs FROM 
      (SELECT value,count(*) as occurs 
      FROM 
      T200 
      GROUP BY value)T2 
     )T3 
     WHERE T1.occurs = T3.maxoccurs)T4 
     GROUP BY occurs; 

Мой вопрос: «Есть ли более простой способ?»

Я думал как использовать HAVING count(*) = max(count(*)) или что-то подобное, чтобы избавиться от дополнительного соединения, но не смог получить HAVING, чтобы вернуть результат, который я хотел.

ОБНОВЛЕНО: как предложено @zneak, я могу упростить T3, как показано ниже:

 SELECT GROUP_CONCAT(value) as modes,occurs 
    FROM 
     (SELECT value,occurs FROM 
      (SELECT value,count(*) as occurs 
      FROM 
      T200 
      GROUP BY value)T1, 
     (SELECT count(*) as maxoccurs 
      FROM 
      T200 
      GROUP BY value 
      ORDER BY count(*) DESC 
      LIMIT 1 
     )T3 
     WHERE T1.occurs = T3.maxoccurs)T4 
     GROUP BY occurs; 

Теперь есть способ, чтобы получить поездку Т3 вообще? Я попытался это, но он не возвращает ни одной строки по какой-то причине

SELECT value,occurs FROM 
    (SELECT value,count(*) as occurs 
    FROM t200 
    GROUP BY `value`)T1 
    HAVING occurs=max(occurs) 

в основном я интересно, если есть способ сделать это таким образом, что я только нужно указать t100 или t200 один раз.

ОБНОВЛЕНИЕ: я нашел способ указать t100 или t200 только один раз, добавив переменным, чтобы установить свои собственные MaxOccurs, как показано ниже

SELECT GROUP_CONCAT(CASE WHEN [email protected] THEN value ELSE NULL END) as modes 
    FROM 
    (SELECT value,occurs,@maxoccurs:=GREATEST(@maxoccurs,occurs) as maxoccurs 
    FROM (SELECT value,count(*) as occurs 
      FROM t200 
      GROUP BY `value`)T1,(SELECT @maxoccurs:=0)mo 
    )T2 
+0

Есть ли «ЗАКАЗ ПО СЧЕТЧИКУ (*) DESC LIMIT 1' work? – zneak

+0

Я не думаю, что это сработает, потому что иногда есть много MODES, как в таблице 't200', есть 2 режима, и я хочу, чтобы они оба вернулись для использования в моей группе_concat –

+0

@zneak, nice Я буду использовать ORDER By count (*) desc LIMIT 1 для T3, но есть ли способ избавиться от T3 –

ответ

5

Вы очень близки с последним запросом. Далее находит один режим:

SELECT value, occurs 
FROM (SELECT value,count(*) as occurs 
     FROM t200 
     GROUP BY `value` 
     LIMIT 1 
    ) T1 

Я думаю, ваш вопрос был о нескольких режимах, хотя:

SELECT value, occurs 
FROM (SELECT value, count(*) as occurs 
     FROM t200 
     GROUP BY `value` 
    ) T1 
WHERE occurs = (select max(occurs) 
       from (select `value`, count(*) as occurs 
         from t200 
         group by `value` 
        ) t 
       ); 

EDIT:

Это намного проще в почти любой другой базе данных. MySQL не поддерживает ни with, ни оконные/аналитические функции.

Ваш запрос (как показано ниже), не делать то, что вы думаете, что делает:

SELECT value, occurs 
    FROM (SELECT value, count(*) as occurs 
     FROM t200 
     GROUP BY `value` 
     ) T1 
    HAVING occurs = max(occurs) ; 

Окончательный having положение относится к переменной occurs но использовать max(occurs). Из-за использования max(occurs) это запрос агрегации, который возвращает одну строку, суммируя все строки из подзапроса.

Переменная occurs не используется для группировки.Итак, какое значение использует MySQL? Он использует произвольное значение из одной из строк в подзапросе. Это произвольное значение может совпадать, иначе оно может не совпадать. Но значение происходит только из одной строки. Итераций нет.

+0

, так что нет способа сравнить непосредственно с max (происходит) от T1? почему мой запрос с 'HAVING' запускается и ничего не возвращает? –

 Смежные вопросы

  • Нет связанных вопросов^_^