2017-08-16 59 views
1

林不知道如何解释这一点。最好的我可以解释它是,我想做一个类似于左连接的东西,只有我想返回连接表的主表匹配条件的子集,但仍然返回所有左连接的行。我希望这是有道理的。过滤器加入,但仍然返回所有行

我有4个表:

公司

服务

ServicesTranslations

CompanyService

,公司可以有许多服务和服务可以有很多翻译。 我想在ServiceTranslation表上筛选给定的搜索词。

我能得到这个工作的唯一方法是在SQL下面,但我觉得也许有更好的更干净的方法来做到这一点,或者我的解决方案好吗?

 DECLARE @defaultLanguage NVARCHAR(5) 

     SET @defaultLanguage = (SELECT LanguageCode FROM LANGUAGE WHERE IsDefault = 1) 

     SELECT 
      c.Id, 
      c.Name, 
      c.OrgNr, 
      c.UserId, 
      c.Address, 
      c.PostalArea, 
      c.County, 
      c.Country, 
      c.Description, 
      c.DescriptionFull, 
      c.Telephone, 
      c.Email, 
      c.Website, 
      c.IsApproved, 
      s.Id, 
      ISNULL(tr.Name, def.Name) Name 

      FROM Company c 

      INNER JOIN CompanyService cs on cs.CompanyId = C.Id 

      INNER JOIN Service s on s.Id = cs.ServiceId 

      LEFT OUTER JOIN ServiceTranslation tr 
      ON s.Id = tr.ServiceId AND tr.LanguageCode = @userLanguage 
      -- join default language of the service: 

      LEFT OUTER JOIN ServiceTranslation def 
      ON s.Id = def.ServiceId AND def.LanguageCode = @defaultLanguage 

      WHERE c.IsApproved = 1 

      AND 
      c.Id IN 
      (
       SELECT c1.Id FROM Company c1 

       INNER JOIN CompanyService cs1 on cs1.CompanyId = c1.Id 

       INNER JOIN Service s1 on s1.Id = cs1.ServiceId 

       INNER JOIN ServiceTranslation tr1 
       ON s1.Id = tr1.ServiceId AND tr1.LanguageCode = @userLanguage 
       -- join default language of the service: 

       INNER JOIN ServiceTranslation def1 
       ON s1.Id = def1.ServiceId AND def1.LanguageCode = @defaultLanguage 



       AND s1.IsApproved = 1 AND ISNULL(tr1.Name, def1.Name) LIKE '%' + @searchQuery + '%' 
     ) 

在此先感谢!

编辑:

我想一些澄清是必需的。我不知道如何以可读格式添加表格数据,所以我附上了表格和所需结果的一些图像。

Company表:

enter image description here

服务表:

enter image description here

ServiceTranslation表:

enter image description here

CompanyService表:

enter image description here

期望的结果(@userLanguage = 'NB-NO' 和@searchquery = '交通'):

它有与所述字服务两家公司的运输'我想要这两家公司加上所有其他服务。

enter image description here

你可以从结果看图像,IM过滤器公司有一个匹配的服务,但还是想回到那些符合公司和所有服务。

我希望这使得它更有点清楚:)

+3

我认为样本数据和预期的结果将真正帮助。你想要返回哪个子集? –

+0

您在主SELECT语句中的s.Id后缺少一个逗号,它包含c.Website,c.IsApproved,s.Id,ISNULL(tr.Name,def.Name)Name' –

+0

@ J.D。对不起,这是一个错字,我现在修好了,谢谢。 – JCoder23

回答

0

使用CTE:

;WITH Comps AS 
(
    SELECT DISTINCT c.CompanyId FROM CompanyService C 
    LEFT JOIN ServiceTranslation tr ON tr.ServiceId = C.ServiceId AND tr.LanguageCode = @userLanguage AND tr.Name LIKE '%' + @searchQuery + '%' 
    LEFT JOIN ServiceTranslation def ON def.ServiceId = C.ServiceId AND def.LanguageCode = @defaultLanguage AND def.Name LIKE '%' + @searchQuery + '%' 
    WHERE tr.ServiceId IS NOT NULL OR def.ServiceId IS NOT NULL 
) 

    SELECT 
     c.Id, 
     c.Name, 
     c.OrgNr, 
     c.UserId, 
     c.Address, 
     c.PostalArea, 
     c.County, 
     c.Country, 
     c.Description, 
     c.DescriptionFull, 
     c.Telephone, 
     c.Email, 
     c.Website, 
     c.IsApproved, 
     s.Id, 
     def.Name 

     FROM Company c 

     INNER JOIN CompanyService cs on cs.CompanyId = C.Id 

     INNER JOIN Service s on s.Id = cs.ServiceId 

     INNER JOIN ServiceTranslation def ON def.ServiceId = s.Id AND def.LanguageCode = @defaultLanguage 

     INNER JOIN Comps CM ON CM.CompanyId = c.Id 

     WHERE c.IsApproved = 1 AND s.IsApproved = 1 

或使用子查询:

SELECT 
      c.Id, 
      c.Name, 
      c.OrgNr, 
      c.UserId, 
      c.Address, 
      c.PostalArea, 
      c.County, 
      c.Country, 
      c.Description, 
      c.DescriptionFull, 
      c.Telephone, 
      c.Email, 
      c.Website, 
      c.IsApproved, 
      s.Id, 
      def.Name 

      FROM Company c 

      INNER JOIN CompanyService cs on cs.CompanyId = C.Id 

      INNER JOIN Service s on s.Id = cs.ServiceId 

      INNER JOIN ServiceTranslation def ON def.ServiceId = s.Id AND def.LanguageCode = @defaultLanguage 

      INNER JOIN Comps CM ON CM.CompanyId = c.Id 

      WHERE c.IsApproved = 1 AND s.IsApproved = 1 AND c.Id IN 
      (
      SELECT DISTINCT c.CompanyId FROM CompanyService C 
      LEFT JOIN ServiceTranslation tr ON tr.ServiceId = C.ServiceId AND tr.LanguageCode = @userLanguage AND tr.Name LIKE '%' + @searchQuery + '%' 
      LEFT JOIN ServiceTranslation def ON def.ServiceId = C.ServiceId AND def.LanguageCode = @defaultLanguage AND def.Name LIKE '%' + @searchQuery + '%' 
      WHERE tr.ServiceId IS NOT NULL OR def.ServiceId IS NOT NULL 
     ) 
+0

我已经尝试过,但只返回匹配搜索参数的公司和服务行。我已经添加了一些更详细的信息来解释后面的内容。谢谢 – JCoder23

+0

感谢您的澄清。更新我提出的解决方案... –

+0

非常感谢,我知道必须有一种更干净的方式来做到这一点!这非常有见地! – JCoder23

相关问题