我有一个基本的多对多表:
tbFilter
filterId | filterName
tbProduct
productId | productName
tbProductFilter
filterId | productId
所以,我有很多产品有很多过滤器(颜色,大小等)。现在,我需要创建一个程序来使用一些过滤器组合来查找产品,例如: 所有产品(蓝色或绿色)和(大OR Xlarge)和(forMen)
我发现创建此查询的唯一方法是使用同一个表的多个连接,每个连接用于“组”过滤器或多个子查询,每个子组用于一个组。最大的问题是多对多表有更多的100k记录,所以这种方法表现不佳。
执行此查询的最佳方法是什么?我正在使用sql 2012。
由于
这就是我现在的工作方式:
select [produtos].* FROM [dbo].[tbProdutos] AS [produtos] JOIN [dbo].tbJuncaoProdutoCategoria] AS [juncaoProdutoCategoria] ON [produtos].[produtoId] = juncaoProdutoCategoria].[produtoId] JOIN [dbo].[tbJuncaoProdutoCategoria] AS juncaoProdutoCategoria2] ON [produtos].[produtoId] = [juncaoProdutoCategoria2].[produtoId] JOIN [dbo].[tbProdutoCategoria] AS [produtoCategoria] ON [produtoCategoria].[categoriaId] = [juncaoProdutoCategoria].[categoriaId] where [juncaoProdutoCategoria].categoriaId = 1 AND ([juncaoProdutoCategoria2].categoriaId = 300 OR [juncaoProdutoCategoria2].categoriaId = 301)
答案 0 :(得分:0)
首先,您肯定想检查索引 - 您需要所有外键字段以及fitlerName上的索引。
假设您的索引处于良好状态,可以采用以下方法:
SELECT p.* -- preferably just select the fields you need here...
FROM products p
WHERE p.productId IN (
SELECT pf.product_id
FROM tbProductFilter pf
WHERE EXISTS (SELECT 1 FROM tbFilter f
WHERE pf.filterId = f.filterId AND f.filterName IN ('blue', 'green'))
AND EXISTS (SELECT 1 FROM tbFilter f
WHERE pf.filterId = f.filterId AND f.filterName IN ('large', 'xlarge'))
AND EXISTS (SELECT 1 FROM tbFilter f
WHERE pf.filterId = f.filterId AND f.filterName = 'forMen')
)
答案 1 :(得分:0)
将过滤器放入表格(或表值参数),将其连接到ProductFilter表,逐个产品,并计算加入的唯一过滤器。
此方法可以处理任意数量的过滤器并执行模糊匹配,即“向我显示与这四个过滤器中的三个相匹配的产品”
DECLARE @filterCount int = 3
DECLARE @filterSet TABLE ( filterNum int, filterName varchar(max) )
INSERT @filterSet VALUES
(1,'blue'),(1,'green'),
(2,'large'),(2,'xlarge'),
(3,'forMen')
SELECT pf.ProductId
FROM tbProductFilter pf
INNER JOIN tbFilter f ON f.filterId = pf.filterId
INNER JOIN @filterSet s ON s.filterName = f.filterName
GROUP BY pf.productId
HAVING COUNT(DISTINCT s.filterNum) = @filterCount