Удаление дубликатов из нескольких самостоятельных левых соединений - PullRequest
3 голосов
/ 22 ноября 2010

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

SELECT count(*) 
FROM rules AS t1 
LEFT JOIN rules AS t2
 ON t1.id != t2.id
 AND ...
LEFT JOIN rules AS t3
 ON t1.id != t2.id AND t1.id != t3.id AND t2.id != t3.id
 AND ...

В настоящее время я удаляю дубликаты, создавая массив идентификаторов из соединенных строк, затем сортируя и группируя их:

SELECT sort(array[t1.id, t2.id, t3.id]) AS ids
...
GROUP BY ids

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

t1.ID | t2.ID | t3.ID
---------------------
  A   |   B   |   C
  C   |   B   |   A

Должно быть

t1.ID | t2.ID | t3.ID
---------------------
  A   |   B   |   C

Или

t1.ID | t2.ID | t3.ID
---------------------
  C   |   B   |   A

Но не оба.

РЕДАКТИРОВАТЬ: Я хотел бы перейти от перестановкистрок в комбинации строк.

Ответы [ 4 ]

4 голосов
/ 22 ноября 2010

Я бы посоветовал вместо того, чтобы присоединиться к! =, Попробуйте присоединиться к <=.</p>

Тогда у вас будут все комбинации с t1.id> t2.id, t2.id> t3.id и так далее.

Строки не будут «дубликатами», потому что они являются упорядоченными наборами, и любой набор, содержащий эквивалентные элементы, обязательно приведет к идентичной упорядоченной совокупности.

3 голосов
/ 22 ноября 2010

Думаю, вы хотите перейти от перестановки строк к комбинации строк?

Если это так, то отдельные ответы неверны. Выберите отличные, чтобы выбрать различные перестановки. Я думаю, у вас есть довольно хороший способ сделать это. Единственное, о чем я могу думать, - это объединить правила в строку и отсортировать ее по месту. Похоже, вы используете Postgresql, и нет функции, которая делает это во встроенных строковых функциях.

Если бы количество символов было небольшим, вы могли бы вставить их в предварительно отсортированный массив, вставив «A» в индексе 1, «B» в индекс 2 и т. Д. Что может привести к более быстрой сортировке ...

2 голосов
/ 22 ноября 2010

Вам нужно оформить заказ в ваших результатах, чтобы отфильтровать все дубликаты.Этого можно достичь, убедившись, что a<b<c.И как только у вас есть порядок в ваших результатах, вы можете применить отличительный к набору результатов.

`ВЫБРАТЬ счетчик (*) ИЗ правил КАК t1

СЛЕДУЮЩИЕ правила СОЕДИНЕНИЯ КАК t2 НА t1.id! = t2.id AND

СЛЕВАЯ ПРИСОЕДИНЯЙСЯ К Правилам, КАК t3 ON t1.id! = t2.id AND t1.id! = t3.id AND t2.id! = t3.id ...

t1.id

AND ... `

1 голос
/ 22 ноября 2010

Трудно точно понять, чего вы пытаетесь достичь, но чтобы избежать дублирования A-B-C C-B-A, попробуйте следующее:

SELECT count(*) 
FROM rules AS t1 
LEFT JOIN rules AS t2
 ON t1.id **<** t2.id
 AND ...
LEFT JOIN rules AS t3
 ON t1.id **<** t2.id AND t1.id **<** t3.id AND t2.id **<** t3.id
 AND ...

Таким образом, ответы всегда упорядочены

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...