将排列转换为行组合的左连接条件
我有一个计划表,例如,
id | service_1 | service_2 | ...
---------------------------------
1 | true | true | ...
2 | true | false | ...
3 | false | true | ...
我通过左连接表本身(任意次数)来生成行的排列。
SELECT t1.id, t2.id, t3.id
FROM plans AS t1
LEFT JOIN plans AS t2
ON t1.id != t2.id
AND ...
LEFT JOIN plans AS t3
ON t1.id != t2.id AND t2.id != t3.id AND t3.id != t1.id
AND ...
如何生成提供 service_1 和 service_2 的所有不同组合,同时避免重复。 连接行不能包含相同的服务例如,
id | service_1 | service_2 | id | service_1 | service_2 |
---------------------------------------------------------
1 | true | true |NULL| NULL | NULL |
2 | true | false | 3 | false | true |
我正在努力解决这种方法的连接条件。另外,这从根本上来说是解决这个问题的错误方法吗?
我试图避免重复的可能方法是:
有序集(我还没有得到这个工作)例如 t1.id
t2.id
sort(array[t1.id,t2.id]) AS ids ... GROUP BY ids
I have a table of plans e.g.
id | service_1 | service_2 | ...
---------------------------------
1 | true | true | ...
2 | true | false | ...
3 | false | true | ...
I am generating the permutation of rows by left joining the table on itself (any number of times).
SELECT t1.id, t2.id, t3.id
FROM plans AS t1
LEFT JOIN plans AS t2
ON t1.id != t2.id
AND ...
LEFT JOIN plans AS t3
ON t1.id != t2.id AND t2.id != t3.id AND t3.id != t1.id
AND ...
How can I generate all the different combinations that provide service_1 and service_2 whilst avoiding duplication. The joining row cannot contain the same service e.g.
id | service_1 | service_2 | id | service_1 | service_2 |
---------------------------------------------------------
1 | true | true |NULL| NULL | NULL |
2 | true | false | 3 | false | true |
I am struggling with the join conditions for this approach. Also, is this fundamentally the wrong approach for solving this problem?
Possible ways I am trying to avoid duplication are:
ordered sets (I am yet to get this working) e.g. t1.id < t2.id
sort(array[t1.id,t2.id]) AS ids ... GROUP BY ids
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想是的。这看起来类似于集合打包问题和/或设置覆盖问题。
我认为通过单个查询来完成此操作是不可行的(或者甚至可能)。您需要与要覆盖的服务一样多的联接,并且许多 WHERE 条件是该数量的函数。
我认为一种简单的、暴力的方法和简单的修剪在这里可能会起作用,因为无论如何你想要的是所有可能组合的列表。或者您可以预先计算所有有效组合并将它们存储在一个大表中。
无论你做什么,这对我来说至少是 O(rowscols) 。
I think so. This looks similar to the set packing problem and/or the set cover problem.
I don't think it would be feasible (or maybe even possible) to do this with a single query. You need as many joins as there are services to be covered, and a number of WHERE conditions a function of that number.
I think a naïve, brute-force approach with simple pruning may work here, since what you want is a list of all the possible combinations anyway. Or you could pre-compute all the valid combinations and store them in a large table.
Whatever you do, this looks like at least O(rowscols) work to me.
假设您的 id 是 1,2,3 4.
SELECT * FROMplans A INNER JOINplans B ON B.Id >= A.id
将为您提供以下集合:我相信是什么您想要的 - 您在计划中拥有全部 2 套组合。
Say you have the id's 1,2,3 4.
SELECT * FROM plans A INNER JOIN plans B ON B.Id >= A.id
will give you the following sets:Which I believe is what you want - you have all 2 set combinations on the plans.
我认为我们没有足够的表结构/样本输入/样本输出。以下似乎回答了我们正在处理的有限情况的问题:
基本上,我们只满足一侧或另一侧有“间隙”的连接(service_x = 0),但总的来说,我们要求没有间隙。
抱歉,如果这看起来很散漫,或者不符合要求。如果您可以在您的问题中添加更多示例以及实际的表格结构,我也许可以做得更好。
I don't think we have enough table structure/sample input/sample output. The following appears to answer the question for the limited case we're dealing with:
Basically, we only satisfy the join where there is a "gap" on one side or the other (service_x = 0), but we require, overall, that there are no gaps.
Sorry if this seems rambling, or doesn't fit the bill. If you could add more samples to your question, and the actual table structure, I may be able to do better.