2016-01-06 2 views
1

Я пытаюсь получить самые частые пары и триплеты (3/3) чисел, моя таблица выглядит так:Получить 20 наиболее часто встречающихся пар (2/2) и триплетов (3/3) чисел

+----+------+------+------+------+------+------+------+------+------+------+ 
| id | nr1 | nr2 | nr3 | nr4 | nr5 | nr6 | nr7 | nr8 | nr9 | nr10 | 
+----+------+------+------+------+------+------+------+------+------+------+ 
| 1 | 1 | 39 | 19 | 23 | 28 | 80 | 3 | 42 | 60 | 32 | 
+----+------+------+------+------+------+------+------+------+------+------+ 
| 2 | 43 | 18 | 3 | 24 | 29 | 33 | 15 | 1 | 61 | 80 | 
+----+------+------+------+------+------+------+------+------+------+------+ 
| 3 | 11 | 25 | 33 | 2 | 30 | 3 | 1 | 44 | 62 | 78 | 
+----+------+------+------+------+------+------+------+------+------+------+ 

Я хочу знать, что входит в тройку наиболее часто встречающихся пар или триплетов чисел из всех моих строк.

Пример:

1,3 (3 раза)

1,80 (2 раза)

3,80 (2 раза) 1,3,80 (2 раза)

Я мог бы попытаться добавить номера в порядке, как 1,2,3, а затем вывести их из базы данных, но все-таки сценарий я придумал это плохо, и занимает несколько часов, чтобы проверить 10000 линий

ny идея приветствуется. спасибо.

+0

Ограничение числа ограничено? Может быть, 1, скажем, 100? – maxhb

+0

Да, они от 1 до 90 – user3092543

+0

Может ли одна и та же строка иметь повторяющиеся значения? как два 80-х? –

ответ

1

Вы должны UNPIVOT таблицы, но MySQL оленьей кожа имеет UNPIVOT функции, так что вы делаете

SQL Fiddle Demo

CREATE TABLE unpivot 
SELECT * 
FROM ( 
     SELECT id, nr1 as n_value FROM tuple union all 
     SELECT id, nr2 as n_value FROM tuple union all 
     SELECT id, nr3 as n_value FROM tuple union all 
     SELECT id, nr4 as n_value FROM tuple union all 
     SELECT id, nr5 as n_value FROM tuple union all 
     SELECT id, nr6 as n_value FROM tuple union all 
     SELECT id, nr7 as n_value FROM tuple union all 
     SELECT id, nr8 as n_value FROM tuple union all 
     SELECT id, nr9 as n_value FROM tuple union all 
     SELECT id, nr10 as n_value FROM tuple 
    ) as T 

Теперь посмотрите на количество пара делает объединение с самими собой.

SELECT n1, n2, count(*) as total 
FROM 
    (
    SELECT up1.n_value as n1, up2.n_value as n2 
    FROM unpivot up1 
    JOIN unpivot up2 
     ON up1.`id` = up2.`id`   
    AND up1.n_value < up2.n_value 
    ) T 
GROUP BY n1, n2 
ORDER BY total desc 
LIMIT 3; 

для тройни вы присоединитесь за столом три раза

SELECT n1, n2, n3, count(*) as total 
FROM 
    (
    SELECT up1.n_value as n1, up2.n_value as n2, up3.n_value as n3 
    FROM unpivot up1 
    JOIN unpivot up2 
     ON up1.`id` = up2.`id`   
    AND up1.n_value < up2.n_value 
    JOIN unpivot up3 
     ON up2.`id` = up3.`id`   
    AND up2.n_value < up3.n_value 
    ) T 
GROUP BY n1, n2, n3 
ORDER BY total desc 
LIMIT 3; 

UPDATE:

Я сделал тестирование на PostGreSQL

Создание 50k строк, со случайными значениями от 1 до 90

После создания индекса запрос требуется всего 2 секунды.

enter image description here

+0

Спасибо за идею, но я действительно не понимаю запрос ... специально часть SELECT up1.n_value? Я получаю ошибку там – user3092543

+0

Я обновляю свой ответ и включаю sqlFiddle –

+0

Да, я проверил это утро, и все выглядит хорошо, но я дошел до одной и той же проблемы ... очень медленно, когда у меня есть 50 тыс. записей :(Идея с univot отлично, но все еще медленный. – user3092543

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