SELECT JOIN in same table ON multiple rows
我有一个带有itemID和categoryID列的表。这两列都是主键,因为每个项可以有一个以上的类别:
1 2 3 4 5 6 7 8
| itemID | catID
-----------------
1 | 2
1 | 3
1 | 4
2 | 2
2 | 3
2 | 4 |
我想选择具有相同类别的项目(基于所有项目类别,而不仅仅是一个),因此我需要加入相同的表。
我希望能够根据指定的itemID找到具有相同catid的itemID。
注:例如,项目1具有类别2、3、4、5、6,而项目2具有类别2、3、4、5、6,而项目3具有类别3、5、6,那么如果我将项目1与项目2和3进行比较,我需要先获取项目2,然后再获取项目3,因为项目2具有比项目3更匹配的类别。显然,所有的项目都需要完成,不仅仅是3个。这样我就可以推荐类似产品的访问者…
- 请不仅提供数据和表结构的示例,还提供预期结果的示例。
- @沃尔克:我不认为预期的结果能被画成表格。预期结果是获得具有相同catid的itemID。所以我可以选择一个与指定的itemID具有相同catid的itemID。
- 如果不能将结果绘制成一个表,那么世界上就没有能够生成它的SQL。这是SQL的原则之一,即结果集本身就是表。也许您应该将您的流程分解为能够找到属于一组特定类别的所有项目,并为所有可能的类别组合调用这些项目。
所以您想选择一个itemID,然后将其与共享一个或多个catid的所有其他itemID匹配?
1 2 3 4
| SELECT DISTINCT c2 .itemID
FROM categories c1
JOIN categories c2 ON c1 .catID = c2 .catID
WHERE c1 .itemID = ? |
号
- 类似的,但按类别匹配最多的项目排序。例如,项目1具有类别2、3、4、5、6,而项目2具有类别2、3、4、5、6,而项目3具有类别3、5、6,那么如果我将项目1与项目2和3进行比较,我需要先获取项目2,然后获取项目3,因为项目2具有比项目3更匹配的类别。显然,所有的项目都需要完成,不仅仅是3个。这样我就可以推荐类似产品的访问者…
- @乔纳森:请把这个"小"修正案编辑成你原来的问题。
基于Bill的初始查询,应该按照匹配的类别数降序排列它(因为联接应该每个匹配返回一行)。我也从结果中排除了正在查询的项目。
1 2 3 4 5 6 7
| SELECT c2 .itemID
FROM categories c1
JOIN categories c2 ON c1 .catID = c2 .catID
WHERE c1 .itemID = :id
AND c2 .itemID <> :id
GROUP BY c2 .itemID
ORDER BY count(c2 .itemID ) DESC ; |
- 类别数不起作用。类别必须相同。
- 当然,它只会返回具有相同类别的项目:)我所说的类别数只是参考后续的排序。
- 看起来它在做我想做的!谢谢。@Siride:你只会说"类别的数量不会"和"如果结果不能被绘制成表格,那么就没有SQL"。如果你有正确的答案,就贴出来。它将有更多帮助…
- 如果我需要按照匹配的类别以及从另一个表中获得的最高投票来排序列表,该怎么办?"投票"表包含两列:"itemid"和"total_value","total_value"是最终费率。你能把更新后的代码分开发布吗?谢谢!
I want to select items with the same categories (based on all the item categories, not just one) so I need to kind of JOIN the same table.
号
在不提及输出的任何其他内容的情况下,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10
| Select C.itemid
From categories As C
Where Exists (
Select 1
From categories As C2
Where C2.catID = C.catID
And C2.itemID <> C.itemID
)
And C.itemID = ?
Group By C.itemid |
。
(来自评论)
Something like that, but ORDERED by items that have the most categories matches. For example item 1 have categories 2,3,4,5,6 and item 2 have categories 2,3,4,5,6 and item 3 have categories 3,5,6 then if i compare item 1 to item 2 and 3 i need to get item 2 first and then item 3 because item 2 have more categories matches than item 3
号
这就给这个问题增加了不同的肤色,这就是为什么你应该在原来的文章中包含预期的输出。从字面上看你所写的:
1 2 3 4 5 6 7 8
| Select C .itemid , Group_Concat (C .catID Order By C .catID ) As Categories
, Count(*) As MatchCount
From categories As C
Join categories As C2
On C2 .itemID <> C .itemID
And C2 .catID = C .catID
Group By C .itemID
Order By Count(*) Desc |
- 嗯,你发布的第二个代码是错误的。首先是C,而不是C1。第二,也是最重要的一点,我在运行代码之后重新启动了服务器,因为Apache出了问题,一切都变慢了。铬停止工作,阿帕奇走了。
- @乔纳森-但是我不能和你的机构说话,我已经改正了打字错误。我假设Categories表在itemID和catid上都有索引?Group_Concat可能是一个昂贵的操作,但是您也没有提到涉及多少行,甚至没有提到您是否真的想要一个连接列表。我们都在猜测你到底在寻找什么。
- 好吧,我想如果我需要比较所有的表格项目,就好像6000多个项目一样。你认为最好的方法是什么?
- @jonathan-首先,如果过滤单个itemID,查询是否返回正确的结果?如果是这样,那么我们正在讨论如何提高效率。
您有多对多关系,因此查询如下:
1 2 3 4
| SELECT item .name
FROM item AS b
JOIN itemcategories AS ab ON b .ID = ab .itemID
where ab .catID =2; |
- 我觉得不对。我希望能够根据指定的itemID找到具有相同catid的itemID。基于项目的所有类别,而不仅仅是一个类别。