我在一个oracle sql数据库中工作,有两个表,一个有一个坏属性组合列表,另一个有一个用户及其属性列表。像这样:
| ComboID| Item1| Item2|
| --|--|--|
| 1 |冰淇淋|热酱料|
| 2 |芦笋|巧克力|
| 3 |花生酱|牛排|
| 4 |芦笋|冰淇淋|
| 用户属性ID|用户|项目|
| --|--|--|
| 1 |A1|冰淇淋|
| 2 |B2|芦笋|
| 3 |A1|巧克力|
| 4 |B2|冰淇淋|
| 5 |C3|牛排|
| 6 |C3|冰淇淋|
| 7 |C3|巧克力|
在本例中,我希望标记用户B2,而不是A1或C3。
我的预期结果是这样的:
| 用户|Bad_Combo_ID|
| --|--|
| B2| 4 |
一般来说,我所尝试的一切似乎要么是不必要的复杂和缓慢,要么是在上面的例子中标记了A1和C3。
3条答案
按热度按时间shyt4zoc1#
根据我对你的问题的理解,你想做这样的事情:
字符串
我根据您的示例数据创建了一个sample fiddle,并为用户D4和E5扩展了一些数据。
我认为结果是正确的,符合你的要求。
此查询如何工作?
首先,我们使用
CTE
构建一个逗号分隔的列表,其中包含属性表中每个用户出现的所有项。然后,我们使用主查询将项目列表与组合表中的项目进行比较。在
INNER JOIN
的ON
子句中,我们说同一行中组合表中的两个项目必须出现在用户的“项目列表”中。如果是这种情况,我们将此用户添加到结果中。所以结果只会显示那些项目组合无效的用户。
ROW_NUMBER
只是创建一个按用户名排序的递增数字。当我读到你的问题时,这就是你想要做的。即使我理解错了什么,答案不是100%你想做的,我认为这应该是一个足够的帮助你指向正确的方向.请让我们知道.
v64noz0r2#
尝试这个简单的sql,其中HAVING子句定义了每个用户是否有来自列ITEM_1和ITEM_2的组合-这是一个糟糕的组合。
字符串
...根据提供的样本数据...
型
.结果:
型
另外,如果您需要查看组合,只需添加c.ITEM_1||‘--’||c.ITEM_2“COMBO”到选择列表,c.ITEM_1、c.ITEM_2到Group By子句。结果应该是:
型
px9o7tmv3#
由于你有固定的组合属性集,你可以使用类似于这个问题的方法:SQL query: Simulating an "AND" over several rows instead of sub-querying。
使用
unpivot
将列转换为行,以列表的形式表示项目,并执行left join
以查找匹配的项目。最后的常数2是组合的项目数(即源表中的列数)。字符串
对于您的示例数据,
的数据
它返回
| 用户_|COMBOID|
| --|--|
| B2| 4 |
fiddle的
请注意,它的伸缩性很好,因为有一个没有函数的等价连接,最有可能导致散列连接。
如果您想缩放此组合以获得无限的组合大小,并将组合项存储为行而不是列,那么它也很容易适应:在CTE中计算组合大小,并在
having
中使用该组合大小而不是常量。型
对于此添加的示例数据:
型
它将返回
| 用户_|COMBOID|
| --|--|
| B2| 4 |
| C3| 5 |
fiddle的