Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.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,我不知道该怎么解释。我所能解释的最好的情况是,我想做一些类似于左联接的事情,只想返回与联接表的条件匹配的主表的子集,但仍然返回所有左联接行。我希望这有点道理 我有4张桌子: 公司 服务 服务贸易 公司服务 一个公司可以有很多服务,一个服务可以有很多翻译。 我想在ServiceTranslation表中筛选给定搜索词 我能让它工作的唯一方法是在下面的SQL中,但我觉得也许有更好更干净的方法来做这件事,或者我的解决方案可以吗 DECLARE @defaultLanguage NVAR

我不知道该怎么解释。我所能解释的最好的情况是,我想做一些类似于左联接的事情,只想返回与联接表的条件匹配的主表的子集,但仍然返回所有左联接行。我希望这有点道理

我有4张桌子:

公司

服务

服务贸易

公司服务

一个公司可以有很多服务,一个服务可以有很多翻译。 我想在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 + '%'
          )
提前谢谢

编辑:

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

公司表:

服务表:

服务翻译表:

公司服务表:

所需结果(@userLanguage='nb NO'和@searchquery='Transport'):

有两家公司的服务中有“运输”一词。我要把这两家公司连同他们的其他服务一起退回

正如您从结果图像中所看到的,im过滤了拥有匹配服务但仍希望返回匹配公司及其所有服务的公司

我希望这能让事情更清楚一点:)

使用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
          )
使用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
          )

我认为样本数据和期望的结果会很有帮助。您想返回哪个子集?您在主SELECT语句=>`c.Website,c.IsApproved,s.Id,ISNULL(tr.Name,def.Name)Name`@J.D.中的s.Id后面缺少一个逗号。很抱歉,这是一个拼写错误,我现在已经修复了它,谢谢。我认为示例数据和所需的结果将非常有用。您要返回哪个子集?您在主SELECT语句=>`c.Website,c.IsApproved,s.Id,ISNULL(tr.Name,def.Name)Name`@J.D.中的s.Id后面缺少一个逗号。很抱歉,这是一个拼写错误,我现在已经修复了它,谢谢。我已经尝试过了,但这只返回与搜索参数匹配的公司和服务行。我添加了更多的细节来解释我想要什么。非常感谢你,我知道必须有更干净的方法!这很有见地!我已经试过了,但只返回与搜索参数匹配的公司和服务行。我添加了更多的细节来解释我想要什么。非常感谢你,我知道必须有更干净的方法!这很有见地!