Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 - Fatal编程技术网

Sql 根据“从一个表中获取结果”;“过滤器”;有效地

Sql 根据“从一个表中获取结果”;“过滤器”;有效地,sql,sql-server,Sql,Sql Server,我有两个表,表A包含销售数据,而表B有表A中的一些列,这些列需要作为过滤器从表A中获取匹配的结果。我可以得到我需要的结果,但这需要很长时间,我怀疑我这样做的效率不是很高。这种逻辑在多个数据库中使用,因此有时表A和表B很小,这只需要一秒钟,而其他数据库则要大得多,每个表中的记录都在10到10万条之间 这是两个表的演示脚本,在生产环境中有比这更多的列,但这说明了一点: Create Table A ( ID int Identity(1,1), City nvarchar(255),

我有两个表,表A包含销售数据,而表B有表A中的一些列,这些列需要作为过滤器从表A中获取匹配的结果。我可以得到我需要的结果,但这需要很长时间,我怀疑我这样做的效率不是很高。这种逻辑在多个数据库中使用,因此有时表A和表B很小,这只需要一秒钟,而其他数据库则要大得多,每个表中的记录都在10到10万条之间

这是两个表的演示脚本,在生产环境中有比这更多的列,但这说明了一点:

Create Table A
(
    ID int Identity(1,1),
    City nvarchar(255),
    State nvarchar(255),
    Zip nvarchar(255),
    Territory nvarchar(255)
)

Insert Into A Values 
('Chicago', 'IL', 'Zip1', 'Territory1'),
('Houston', 'TX', 'Zip2', 'Territory2'),
('Atlanta', 'AL', 'Zip3', 'Territory3'),
('Denver', 'CO', 'Zip4', 'Territory4'),
('Detroit', 'MI', 'Zip5', 'Territory1'),
('Seattle', 'WA', 'Zip6', 'Territory5'),
('Springfield', 'IL', 'Zip7', 'Territory1'),
('Springfield', 'MO', 'Zip8', 'Territory1'),
('Tacoma', 'WA', 'Zip10', 'Territory5'),
('Portland', 'OR', 'Zip10', 'Territory5' )


Create Table B
(
    ID int Identity(1,1),
    City nvarchar(255),
    State nvarchar(255),
    Zip nvarchar(255),
    Territory nvarchar(255)
)

Insert Into B Values
('Chicago', NULL, NULL, NULL),
('Springfield', 'IL', NULL, 'Territory1'),
(NULL, NULL, 'Zip2', NULL),
(NULL, 'WA', NULL, 'Territory5')
我必须获得所需的记录,如下所示:

Select * 
from A inner join B
on A.City like Coalesce(B.City, A.City)
and A.State like Coalesce(B.State, A.State)
and A.Zip like Coalesce(B.Zip, A.Zip)
and A.Territory like Coalesce(B.Territory, A.Territory)
--More joins in production for remaining columns

这是可行的,但由于记录的数量和额外的连接,我们需要一些数据库的时间。有没有什么方法可以加快这个速度,或者更有效地处理这个我看不到的问题?

首先,强烈建议不要对字符串使用
之类的
,除非您没有任何选择,除了您的业务之外,我想您的查询速度会更快,只需做如下一些更改:

Select * 
from A inner join B
on (A.City =B.City OR B.City IS NULL)
and (A.State =B.State OR B.State IS NULL)
and (A.Zip =B.Zip OR B.Zip IS NULL)
and (A.Territory =B.Territory OR B.Territory IS NULL)

如果这四列(
a.City
a.State
a.Zip
a.Territory
)中至少有一列具有索引,则包含条件的精确匹配可能是更好的选择:

SELECT * 
  FROM A 
  JOIN B
    ON CASE WHEN B.City is null THEN A.City ELSE B.City END = A.City
   AND CASE WHEN B.State is null THEN A.State else B.State END = A.State 
   AND CASE WHEN B.Zip is null THEN A.Zip ELSE B.Zip END = A.Zip
   AND CASE WHEN B.Territory is null THEN A.Territory ELSE B.Territory END = A.Territory

我在where子句中考虑了一个ISNULL选项,而不是CASE选项,但听起来好像你有选项

Select * 
from A inner join B
on (A.City = isnull(B.City, A.City))
and (A.State = isnull(B.State, A.State))
and (A.Zip = isnull(B.Zip, A.Zip))
and (A.Territory = isnull(B.Territory, A.Territory))

除了精确匹配之外,在用于连接表的列上创建索引还可以加快查询速度

您是否有能力检查/更新索引?这可能是你的第一步。我也会重新考虑实际加入;如果我没弄错的话,联合可能会减慢速度。还要检查查询上的执行计划。我会根据你给出的内容,考虑可能的重写。是的,可以并且已经根据执行计划更新了索引,这很有帮助,但没有我预期的那么多。我也尝试过ISNULL,但似乎同时得到了一个评论而不是答案!我不能不使用,比如,有些列是商业名称。所以我们得到了像abc inc和abc co这样的东西。所以表B被作为abc(%)提供给我们,以捕获所有迭代。这就解释了为什么isnull和coalesce之间没有区别。如果您被迫使用like语法,至少您可以从查询中删除coalesce