过滤加入但仍返回所有行

时间:2017-08-16 19:13:26

标签: sql sql-server

我不确定如何解释这一点。我可以解释的最好的是我想做类似于左连接的事情,只是我想返回连接表的主表匹配条件的子集,但仍然返回所有左连接的行。我希望这有点道理。

我有4张桌子:

公司

服务

ServicesTranslations

CompanyService

公司可以拥有多项服务,而服务可以拥有多种翻译服务。 我想过滤给定搜索词的ServiceTranslation表。

我可以让这个工作的唯一方法是在下面的SQL中,但我觉得也许有一个更好的更清洁的方法,或者我的解决方案是否正常?

required_with_all

提前致谢!

编辑:

我认为需要做出一些澄清。我不知道如何以可读格式添加表格数据,所以我附上了一些表格和期望结果的图像。

公司表:

enter image description here

服务表:

enter image description here

ServiceTranslation表:

enter image description here

CompanyService表:

enter image description here

期望的结果(@userLanguage ='nb-NO'和@searchquery ='Transport'):

有两家公司的服务中包含“运输”一词。我希望这两家公司返回以及所有其他服务。

enter image description here

从结果图片中可以看出,im过滤了具有匹配服务的公司,但仍希望返回那些匹配公司及其所有服务。

我希望这更清楚一点:)

1 个答案:

答案 0 :(得分: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

OR与子查询:

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
          )