3

基本上我有 3 个这样的表(具有多对多关系); 在此处输入图像描述 我正在查询这样的搜索;

ALTER PROC [dbo].[usp_ContactSearch]  
(  
 @PersonName varchar(60)= '',  
 @MobileNo varchar(20)= '',  
 @Nationlity varchar(50)='' ,
 @ContactTypes varchar(max) = ''
)  
AS  
BEGIN  
   
  SELECT DISTINCT c.ContactId, c.PersonName, ct.ContactType, ct.ContactTypeId
  
  FROM Contact c  
  LEFT OUTER JOIN ContactWithContactType cct
  ON c.ContactId = cct.ContactId
  LEFT OUTER JOIN ContactType ct
  ON cct.CountactTypeId = ct.ContactTypeId
  
  WHERE   
   c.PersonName LIKE CASE WHEN @PersonName='' THEN c.PersonName ELSE '%'+@PersonName+'%' END  
  AND   
   c.MobileNo1 LIKE CASE WHEN @MobileNo='' THEN c.MobileNo1 ELSE '%'+@MobileNo+'%' END  
  AND   
   c.Nationality LIKE CASE WHEN @Nationlity='' THEN c.Nationality ELSE '%'+@Nationlity+'%' END  

END

所以,默认的结果数据是;
在此处输入图像描述
所以,从前端,我有ContactTypes(这是动态的,即来自联系人类型表),界面看起来像这样

在此处输入图像描述
现在,每当用户检查PropertyOwner (ContactTypeId=1) 时,数据应该被过滤,并且只有那些属于ContactTypeId=1的联系人应该被显示 ,当我检查第二个复选框时,即租户(ContactTypeId=2)。数据应该进行更多过滤,并且只显示属于 ContactTypeId= 1 和 2 的那些联系人。类似地,对于第 3 个 ContactType,数据应该进行更多过滤,依此类推。
所以,问题是ContactTypes是动态的,我不知道如何处理这种情况。
非常感谢有关查询和性能的任何帮助。

4

3 回答 3

1

试试这个。这将工作...

-- This is User Defined Table Type Variable
Declare @MyTypeDataType ContType 
-- You will pass value to this variable from Front End
Insert into @MyTypeDataType values(1),(2),(3);
-- From Front end you will pass the 
-- selected values to "Table Type Variable" and 
-- also to a "Varchar" Variable
Declare @Type as Varchar(20);
SET @Type = '1,2,3';

SELECT X.* FROM 
(
    -- This query will get all persons, 
     -- who have any one Type u want to Search...
    SELECT      C.*,CTT.ContactType, CTT.ContactTypeId FROM Contact C
    INNER JOIN  ContactWithType CT
    ON          C.ContactId = CT.ContactId
    INNER JOIN  ContactType CTT 
    ON          CTT.ContactTypeId = CT.ContactTypeId
    WHERE       @Type LIKE '%' + CAST(  CT.ContactTypeId AS VARCHAR(MAX)) + '%'
) X
INNER JOIN 
(
    -- This will count the Record of each Person,
    -- how many time a persons record exists..
    SELECT      C.ContactId, COUNT(C.ContactId) AS Total    
    FROM        Contact C
    INNER JOIN  ContactWithType CT
    ON          C.ContactId = CT.ContactId
    INNER JOIN  ContactType CTT 
    ON          CTT.ContactTypeId = CT.ContactTypeId
    WHERE       @Type LIKE '%' + CAST(  CT.ContactTypeId AS VARCHAR(MAX)) + '%'
    GROUP BY    C.ContactId
)Y
ON  X.ContactId = Y.ContactId
-- Filter persons
AND  Y.Total = (SELECT COUNT(*) FROM @MyTypeDataType)
于 2013-10-08T02:23:07.880 回答
0

我想建议您对查询使用拆分功能来过滤 ContactTypes。例如,当有人在您的表单中检查 Property Owner 和 Tenant (contactType = 1, 2) 等时,您可以将其传递给您的存储过程

@ContactTypes varchar(max) = '1,2'

然后您可以使用您需要创建的拆分字符串函数之一。你可以参考这篇优秀的文章(http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings)。我使用文章函数SplitStrings_Moden进行简单的字符串拆分。

然后你可以像这样在你的存储过程中使用它。

And ContactType in (select [item] from SplitStrings_Moden(@ContactTypes , ','))

至于性能方面,给出的示例返回一个字符串列表,在您的情况下,您可以将其转换为 int 以获得更好的性能。但我想你可能会在你的数据集上测试它,如果没有强制转换的性能是合理的。

于 2013-10-06T19:01:55.937 回答
0

我建议为此使用 xml 数据类型。您可以在这里找到更多信息。

使用 XML 作为 SP 的输入变量

于 2013-10-07T06:26:30.617 回答