Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询具有多个或/和的多对多表_Sql_Sql Server_Join_Many To Many - Fatal编程技术网

Sql 查询具有多个或/和的多对多表

Sql 查询具有多个或/和的多对多表,sql,sql-server,join,many-to-many,Sql,Sql Server,Join,Many To Many,我有一个基本的多对多表,即: tbFilter filterId | filterName tbProduct productId | productName tbProductFilter filterId | productId 所以,我有很多产品,有很多过滤器(颜色、尺寸等)。现在,我需要创建一个过程,用一些过滤器组合查找产品,如: 所有产品(蓝色或绿色)和(大型或大型)和(forMen) 我发现创建此查询的唯一方法是使用同一表的多个联接,每个联接用于一个“组”筛选器,或者使用多

我有一个基本的多对多表,即:

tbFilter
filterId | filterName


tbProduct
productId | productName


tbProductFilter
filterId | productId
所以,我有很多产品,有很多过滤器(颜色、尺寸等)。现在,我需要创建一个过程,用一些过滤器组合查找产品,如: 所有产品(蓝色或绿色)和(大型或大型)和(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)

首先,您肯定要检查您的索引-您需要所有外键字段以及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')
)

将过滤器放入一个表(或表值参数),将其连接到ProductFilter表,按产品分组,并计算加入的唯一过滤器

此方法可以处理任意数量的过滤器并执行模糊匹配,即“显示匹配这四个过滤器中三个的产品”


这些表上有什么索引?另外,您能展示一下您在这个示例中尝试的查询吗?我刚刚发送了我正在使用的查询。我正在寻找的是一个更好的方法,我不需要加入每个过滤器“组”,谢谢你的解决方案!这会使tbProductFilter上的多个用户在哪里更好?这可能-只有通过尝试和/或查看查询计划才能绝对确定。谢谢!我做了一个快速测试,我想这将完全符合我的需要。我将在SP中进行转换并进行一些性能测试!
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