Removing duplicates from multiple independent left unions

I dynamically generate a query like the one below, which creates different combinations of rules by combining on the left (any number of times) by itself and avoids rules with some of the same attributes as part of the join conditions, for example.

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 ...

I am currently deleting duplicates by creating an array of identifiers from concatenated strings, then sorting and grouping them:

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

I would like to know if there is a better way to remove duplicate lines, for example.

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

Must be

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

or

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

But not both.

EDIT: I would like to switch from line permutation to string combination.

+3
source share
4

, ! =, < =.

t1.id > t2.id, t2.id > t3.id ..

"", , , , .

+4

, , ?

, . . , . , , - . , Postgresql, , .

, , , "A" 1, "B" 2 .. ...

+3

, . , , a<b<c. , .

` SELECT count (*) FROM AS t1

Rules LEFT JOIN AS t2 ON t1.id! = T2.id AND

Rules LEFT JOIN AS t3 ON t1.id! = T2.id And t1.id! = T3.id And t2.id! = T3.id ...

t1.id <t2.id and t2.id <t3.id ...

And ... `

+2
source

It's hard to understand exactly what you are trying to achieve, but to avoid duplication of ABC CBA, try the following:

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 ...

Thus, the answers are always ordered

+1
source

Source: https://habr.com/ru/post/1776155/


All Articles