我正在动态生成一个类似于下面的查询,通过左边连接(任意次数)创建不同的规则组合,并避免使用具有某些相同属性的规则作为连接条件的一部分,例如
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 ...
我目前正在删除重复项,方法是从已连接的行创建一个ID数组,然后按它们进行排序和分组:
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
但不是两个。
编辑:我想从行的排列变为组合行。
答案 0 :(得分:4)
我建议而不是加入!=,尝试加入< =。
然后,您将拥有t1.id>的所有组合。 t2.id,t2.id> t3.id,等等。
行不会是'重复',因为它们是有序集,任何包含等效成员的集都必然会产生相同的有序集。
答案 1 :(得分:3)
我认为你的意思是你想从行的排列变为组合行?
如果是这样,选择不同的答案是错误的。选择distinct将选择不同的排列。我认为你有一个非常好的方法。我唯一能想到的就是将规则连接成一个字符串并将其排序。看起来你正在使用Postgresql,并且没有内置字符串函数中的功能。
如果符号数量很小,您可以将它们插入到预先排序的数组中,方法是在索引1中插入'A',在索引2中插入'B'等等。这可能会更快排序......
答案 2 :(得分:2)
您需要在结果中获取订单,以便过滤掉所有重复项。这可以通过确保a<b<c
来实现。一旦您的结果中有订单,您就可以对结果集应用不同的。
` SELECT count(*)FROM rules AS t1
LEFT JOIN规则AS t2 ON t1.id!= t2.id AND
LEFT JOIN规则AS t3 ON t1.id!= t2.id AND t1.id!= t3.id AND t2.id!= t3.id ......
t1.id&lt; t2.id和t2.id&lt; t3.id ...
AND ...`
答案 3 :(得分:1)
很难准确理解你想要实现的目标,但要避免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 ...
这样,答案总是有序的