Sql 获取多个子行满足不同条件的父行
在我的数据库中有两个表:Sql 获取多个子行满足不同条件的父行,sql,sql-server,Sql,Sql Server,在我的数据库中有两个表:T\u INDEX,和T\u INDEXCALLER。这是一对多的关系。每个索引记录可以有多个调用者(由IndexId引用) 在我的应用程序前端,我有两个搜索字段:名称和扩展名。这两个字段都引用T_INDEXCALLER表。在我的搜索算法中,我需要能够“和”这两个字段。我需要返回T_索引记录,其中包含一个或多个子记录,其中“Name”匹配,并且包含一个或多个子记录,其中“Extension”匹配 这是我当前使用的查询: DECLARE @name varchar(100)
T\u INDEX
,和T\u INDEXCALLER
。这是一对多的关系。每个索引记录可以有多个调用者(由IndexId
引用)
在我的应用程序前端,我有两个搜索字段:名称和扩展名。这两个字段都引用T_INDEXCALLER
表。在我的搜索算法中,我需要能够“和
”这两个字段。我需要返回T_索引
记录,其中包含一个或多个子记录,其中“Name”匹配,并且包含一个或多个子记录,其中“Extension”匹配
这是我当前使用的查询:
DECLARE @name varchar(100);
DECLARE @extension varchar(100);
SET @name = 'fox';
SET @extension = '9039';
SELECT *
FROM T_INDEX
WHERE T_INDEX.IndexId IN (SELECT IndexId FROM T_INDEXCALLER WHERE Name = @name)
AND T_INDEX.IndexId IN (SELECT IndexId FROM T_INDEXCALLER WHERE ExtensionNumber = @extension)
这是可行的,但效率不高。大约有1000万条索引记录,甚至更多的呼叫者记录。是否有一种方法可以使用连接重新编写此搜索查询,从而消除对内部选择的需要(并且更高效)
我遇到的问题是,当我用连接重新编写它时,我只会得到T_INDEX
记录,这些记录有一个子记录,其中两个条件在同一个子记录上匹配。我想获取T_INDEX
记录,这些记录有一个与name条件匹配的子记录,以及一个与extension number条件匹配的单独的子记录。我可以先使用exists
编写此文件:
SELECT i.*
FROM T_INDEX i
WHERE EXISTS (SELECT 1
FROM T_INDEXCALLER ic
WHERE ic.Name = @name AND i.IndexId = ic.IndexId
) AND
EXISTS (SELECT 1
FROM T_INDEXCALLER ic
WHERE ic.ExtensionNumber = @extension AND i.IndexId = ic.IndexId
);
这可以利用索引T\u INDEXCALLER(indexId、Name、ExtensionNmber)
这可能会提供一些加速。另一种选择是:
SELECT i.*
FROM T_INDEX i JOIN
(SELECT ic.indexId
FROM ((SELECT ic.indexId, 1 as priority
FROM T_INDEXCALLER
WHERE ic.ExtensionNumber = @extension
) UNION ALL
(SELECT ic.indexId, 2 as priority
FROM T_INDEXCALLER
WHERE ic.Name = @name
)
) ic
GROUP BY ic.indexId
HAVING MIN(priority) = 1 AND MAX(priority) = 2
) ic
ON ic.indexId = i.indexId;
这可以利用T\u INDEXCALLER(name,indexId)
,T\u INDEXCALLER(ExtensionNumber,indexId)
,以及(非常重要的)T\u INDEX(indexId)
,我不确定您是如何应用连接逻辑的,但基于您的需求,在ON
子句中使用OR条件应该可以完成这项工作
SELECT *
FROM
T_INDEX A INNER JOIN T_INDEXCALLER B
ON A.IndexId = B.IndexId
AND (B.Name = @name OR B.ExtensionNumber = @extension);
我不能说执行速度有多快,但如果没有任何效果,您可以使用这个作为替代方案。您的意思是对于给定的IndexId
,如果T\u INDEXCALLER
中有一个子记录具有name='fox'
但扩展名'9039',另一个子记录具有name'fox'`但扩展名='9039'
,则您希望这两个子记录都显示在给定的T\u索引.IndexId
下。对吗?对。但是,它也可能在同一个儿童记录中。谢谢你的建议。我试试看。EXISTS
是否比内部的SELECT
快?@Gordon-如果我错了,很抱歉,但是您不应该使用或条件(而不是AND)来处理您的两个EXIST查询吗?好的。谢谢@MattSpinksI,我会尝试一下。谢谢你的反馈。不幸的是,这给了我相同的结果(在同一子记录上必须满足这两个条件)。