![]() |
|
Помогите с SQL запросом | ☑ | ||
---|---|---|---|---|
0
alexexe
20.07.13
✎
04:53
|
Здравствуйте!
Помогите, пожалуйста, с реализацией запроса. Не могу понять каким образом лучше сделать - есть таблица CREATE TABLE tbl(id INT PRIMARY KEY, p1 INT, p2 INT, p3 INT, p4 INT, ..., p15 INT); Поля p(n) - принимают значения от [0;2] Необходимо вывести записи, у которых все поля p(n) уникальные, две записи, которые различаются только по 1 полю (если таких пар больше чем одна, то вывести все, если записей отличающихся на одно поле больше чем 2, то не выводить), 3 записи, различающиеся по 2 полям и так до 5 полей Т.е. в результате должно получиться что-то подобное Единственные записи: 1 | 211111211121111 3 | 201010201020101 Записи различающиеся на одну 234 | 201111111011111 412 | 101111111011110 ----------------------- 123 | 100000000000000 321 | 000000000000000 Записи, различающиеся на две 111 | 120000000000000 112 | 010000000000000 113 | 210000000000000 ----------------------- 114 | 222122222201111 115 | 222022222211111 222 | 222222222211111 И т.д. Что примерно можно сделать, оптимальное с точки зрения производительности? С уникальными 15 записями все легко, выбрать записи с уникальным параметрами, но как сделать остальное. Либо регулярки, либо группировки по всем возможным вариантам, больше ничего не приходит в голову Заранее спасибо |
|||
1
фобка
20.07.13
✎
08:07
|
115 отличается от 222 на одну, т.е. Попадет в два набора. Группировку здесь не сделаешь, по ней только дубли..в целом, по задаче теряюсь - на скале непонятно как можно сделать
|
|||
2
Vladal
20.07.13
✎
08:08
|
Задай этот вопрос на sql.ru/forum
|
|||
3
Rie
модератор
20.07.13
✎
10:13
|
(0) Попробуй соединить таблицу саму с собой. Тогда строка соединение - это пара записей. Подсчитаешь различия.
|
|||
4
Бывший адинэсник
20.07.13
✎
10:55
|
(0) по сути у тебя числа в троичной системе, можно использовать арифметические действия, не?
|
|||
5
DmitrO
20.07.13
✎
11:10
|
1.преобразовать таблицу чтобы одна запись содержала идентификатор, номер поля, значение поля (нормализовать)
2.соединить саму с собой по номеру поля и значение из одной не равно значение из другой 3.сгруппировать с подсчетом количества по паре идентификаторов из обоих таблиц 4. полученные идентификаторы записей отобранные с условиями по количеству не совпадений будут ответами на каждый их вопросов: 1 вопрос количество = 15 2 вопрос количество = 1 и так далее |
|||
6
DmitrO
20.07.13
✎
11:20
|
что типа этого для 4х полей:
if object_id('t') is not null drop table t create table t (id int, p int, v int constraint pk primary key clustered (id, p)) insert t select 1, 1, 0 union all select 1, 2, 0 union all select 1, 3, 0 union all select 1, 4, 0 union all select 2, 1, 0 union all select 2, 2, 0 union all select 2, 3, 0 union all select 2, 4, 1 union all select 3, 1, 0 union all select 3, 2, 0 union all select 3, 3, 1 union all select 3, 4, 1 union all select 4, 1, 0 union all select 4, 2, 1 union all select 4, 3, 1 union all select 4, 4, 1 union all select 5, 1, 1 union all select 5, 2, 1 union all select 5, 3, 1 union all select 5, 4, 1 select t.id, t2.id, count(*) as c from t inner join t as t2 on t.p = t2.p and t.v != t2.v group by t.id, t2.id |
|||
7
alexexe
20.07.13
✎
13:42
|
(1) Извиняюсь, за заблуждение - пример не совсем верный
111 | 120000000000000 112 | 010000000000000 113 | 210000000000000 не должно выходить, потому что условие строгое, должны попадать записи, у которых РОВНО две, отличающиеся друг от друга (в ином случае, последние две записи попадают в выборку с одним отличиям - дублей нет) (2) Задал, посоветовали развернуть параметры, как предложил DmitrO (4) в принципе можно, я думал над этим, только ни до чего толкового не додумался... если бы еще это бинарная матрица была, тогда можно было побитовую маску применить. А так - не хватило мозгов (5) Спасибо, самый хороший вариант, только сделал inner join t as t2 on t.p = t2.p and t.v = t2.v, чтобы задавать вопрос - сколько совпадений должно быть Единственный минус - для 100 тысяч записей этот запрос будет выполняться на среднем железе оочень долго... |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |