减少SQL存储过程中的比较次数

减少SQL存储过程中的比较次数,sql,sql-server,Sql,Sql Server,我创建了一个存储过程 以下是要求: 第一个匹配是在公司名和人名上完成的 如果未找到匹配项,则应在地址、城市和人名上进行第二次匹配 若未找到匹配项,则应在zip和人名上进行第三次匹配 我写的是 exec('insert into ProcessedFile_'+@fileuplodedId +' ('+@ConcatAppendedField+ ',UploadedB2bFiled_id) select '+@concatAppendFieldForSelect +',B2bFiled_id

我创建了一个存储过程

以下是要求:

  • 第一个匹配是在公司名和人名上完成的
  • 如果未找到匹配项,则应在地址、城市和人名上进行第二次匹配
  • 若未找到匹配项,则应在zip和人名上进行第三次匹配
我写的是

exec('insert into ProcessedFile_'+@fileuplodedId +' ('+@ConcatAppendedField+ ',UploadedB2bFiled_id) select '+@concatAppendFieldForSelect +',B2bFiled_id from UploadedFile_'+@fileuplodedId+' a , b2bdb b where ((a.CompanyDomain = b.domain and ISNULL(a.CompanyDomain,'''') <> '''' and a.CompanyDomain is not null and a.Name=b.Name)) group by B2bFiled_id,' + @concatAppendFieldForGroupBy ) 

exec('insert into ProcessedFile_'+@fileuplodedId +' ('+@ConcatAppendedField+ ',UploadedB2bFiled_id) select '+@concatAppendFieldForSelect +',B2bFiled_id from UploadedFile_'+@fileuplodedId+' a , b2bdb b where (((a.CompanyDomain is null or a.CompanyDomain !=b.domain) and a.Address1 = b.address and a.City = b.city and a.Name = b.Name )) group by B2bFiled_id,' + @concatAppendFieldForGroupBy) 

exec('insert into ProcessedFile_'+@fileuplodedId +' ('+@ConcatAppendedField+ ',UploadedB2bFiled_id) select '+@concatAppendFieldForSelect +',B2bFiled_id from UploadedFile_'+@fileuplodedId+' a , b2bdb b where ((((a.CompanyDomain is null or a.CompanyDomain !=b.domain) and (a.Address1 = b.address and a.City = b.city and a.Name = b.Name )) and a.Zip = b.Zip and a.Name = b.Name )) group by B2bFiled_id,' + @concatAppendFieldForGroupBy)`
exec('insert into ProcessedFile_'+@fileuplodedId++'('+@ConcatAppendedField++',UploadedB2bFiled_id)选择'+@concatAppendFieldForSelect++',B2bFiled_id from UploadedFile_'+@fileuplodedId++'a,b2bdb,其中((a.CompanyDomain=b.domain,ISNULL(a.CompanyDomain,''''''),a.CompanyDomain不为null,a.Name=b.Name))分组依据B2B文件id,'+@concatAppendFieldForGroupBy)
exec('insert into PROCESSED FILE++@fileuplodedId++'('++@ConcatAppendedField++',UPLOADEDB2B文件id)选择'++@CONCATAPPENDFIELD FORSELECT++',B2B文件id来自UploadedFile++@fileuplodedId++'a,b2bdb其中((a.CompanyDomain为null或a.CompanyDomain!=b.domain)和a.Address1=b.address和a.City=b.City和a.Name=b.Name))分组依据B2B文件id,'+@concatAppendFieldForGroupBy)
exec('insert into PROCESSED FILE++@fileuplodedId++'('++@ConcatAppendedField++',UPLOADEDB2B文件id)从UploadedFile++@fileuplodedId++'a中选择'++@CONCATAPPENDFIELD FORSELECT++',B2B文件id,其中(((a.CompanyDomain为null或a.CompanyDomain!=b.domain)和(a.Address1=b.address和a.City=b.City和a.Name=b.Name))和a.Zip=b.Zip和a.Name=b.Name)按B2B文件id分组,“+@concatAppendFieldForGroupBy)`
但这绝对是低效的,因为在每个语句(第一个语句除外)中,我都在比较我之前所做的所有字段,就像在第一个语句中,我比较了公司名和人名,在第二个语句中,我再次比较了这些字段(公司名和人名)


如何摆脱这个

您可以在每次插入后添加
RETURN
语句,以便在插入行时退出批处理。这样,您就不必从上一个查询中删除条件。e、 g

DECLARE @QueryStart NVARCHAR(1000), @QueryEnd NVARCHAR(1000)
SET @QueryStart = ' INSERT INTO ProcessedFile_' + @FileUploadID + 
                ' (' + @ConcatAppendField + ', UploadedB2bFiled_ID) ' + 
                ' SELECT ' + @ConcatAppendFieldForSelect + ', B2bFiled_ID ' + 
                ' FROM UploadFile_' + @FileUploadedID + ' a, B2bDB b '

SET @QueryEnd = ' GROUP BY B2bFiled_ID, ' + @ConcatAppendFieldForGroupBy    

DECLARE @Query NVARCHAR(1000)
SET @Query = @QueryStart + 
            ' WHERE a.CompanyDomain = b.Domain ' + 
            ' AND   ISNULL(a.CompanyDomain, '''') != '''' ' + 
            ' AND   a.CompanyDomain IS NOT NULL ' +
            ' AND   a.Name = b.Name ' +
            @QueryEnd

EXECUTE SP_EXECUTESQL @Query

IF (@@ROWCOUNT > 0)
    RETURN

SET @Query = @QueryStart + 
            ' WHERE a.Address1 = b.Address ' + 
            ' AND   a.City = b.City ' + 
            ' AND   a.Name = b.Name ' + 
            @QueryEnd

EXECUTE SP_EXECUTESQL @Query

IF (@@ROWCOUNT > 0)
    RETURN

SET @Query = @QueryStart + 
            ' WHERE a.Zip = b.Zip ' + 
            ' AND   a.Name = b.Name ' + 
            @QueryEnd

EXECUTE SP_EXECUTESQL @Query
我复制了你们的条款,但值得指出的是,下面的where条款可以简化

WHERE a.CompanyDomain = b.Domain
AND   ISNULL(a.CompanyDomain, '') != '' 
AND   a.CompanyDomain IS NOT NULL
由于NULL不等于任何东西,甚至不等于NULL,如果a.CompanyDomain为NULL,则它永远不能等于b.Domain,因此可以简化为

WHERE NULLIF(a.CompanyDomain, '') = b.Domain
ADENDUM

好的,正如我现在理解的,如果第一个查询返回结果,您不想中止执行,您只想从第二个查询中排除第一个查询插入的任何内容,从第三个查询中排除第一个和第二个查询插入的任何内容,以避免重复插入?如果是这种情况,我认为您可以通过将所有条件组合到一个查询中来解决这个问题:

DECLARE @Query NVARCHAR(1000)
SET @Query = ' INSERT INTO ProcessedFile_' + @FileUploadID + 
            ' (' + @ConcatAppendField + ', UploadedB2bFiled_ID)
            SELECT ' + @ConcatAppendFieldForSelect + ', B2bFiled_ID
            FROM    UploadFile_' + @FileUploadedID + ' a 
                    INNER JOIN B2bDB b 
                        ON a.Name = b.Name
            WHERE   NULLIF(a.CompanyDomain, '''') = b.Domain
            OR      (a.Address1 = b.Address AND a.City = b.City) 
            OR      a.Zip = b.Zip
            GROUP BY B2bFiled_ID, ' + @ConcatAppendFieldForGroupBy  

EXECUTE SP_EXECUTESQL @QUERY

如果这不是必需的,我认为您可能必须使用原始的3个插入解决方案,因为听起来您使用的是第二个查询中第一个查询插入的数据,第三个查询中第一个和第二个查询插入的数据。

如果您不强迫我们工作,您会得到更多的响应,只是为了能够阅读您的问题和(可能的话)帮你。例如,在句子开头大写并格式化SQL查询以便于阅读。如果公司名称和地址、城市和人名都匹配,则输出表中会有两个更新,一个是公司名称,另一个是地址、城市,人名。我想要的是,如果详细信息与公司名匹配,那么他们就不需要再匹配地址、城市、人名。无论如何,非常感谢@GarethD。对不起,已将
@@ROWCOUNT=0
更改为
@@ROWCOUNT>0
。如果第一个查询中的公司名称和名称匹配,则不会执行第二个查询。如果第二个查询中存在匹配项,则第三个查询将不会执行。假设我们有一个表,其中包含一些comapny域、地址、城市和人名。在执行上述操作时,首先我们有一些域匹配项ok,然后在更新执行终止后,我们将跳过与address、city、name匹配的数据。我经常打扰你@GarethD?