使用带有INNER JOIN查询的STUFF

时间:2018-05-04 01:45:37

标签: sql sql-server select

我的数据库中有三个表。用于Product的表,用于Types的表和名为Prod_Type的映射表。我的数据库是sql server,这就是为什么我不能使用group_concat函数而我正在使用Stuff函数。我的表结构如下

的productTable

Prod_ID    |   Name    |   Brand
-------        ----        -----
   1       |   Name1   |   Brand1
   2       |   Name2   |   Brand2
   3       |   Name3   |   Brand3
   4       |   Name4   |   Brand4
   5       |   Name5   |   Brand5
   6       |   Name6   |   Brand6
   7       |   Name7   |   Brand7

TypeTable

 Type_ID   |   TypeName
 -------       --------
    1      |   TypeName1
    2      |   TypeName2
    3      |   TypeName3
    4      |   TypeName4
    5      |   TypeName5

Prod_TypeTable

  Prod_IDM   |  Type_ID
  --------      -------
     1      |     1
     1      |     3
     1      |     4
     1      |     5
     2      |     2
     2      |     3
     3      |     4
     4      |     5
     4      |     1
     5      |     4
     5      |     3
     5      |     2
     6      |     2
     6      |     3
     7      |     5

我能够将产品表加入到Prod_type的映射表中。我使用东西查询来避免多个结果。我的查询是这样的:

Select 
  top 5 * 
from  ProductTable 
   inner Join (SELECT  
                 Prod_IDM, 
                 STUFF((SELECT ', ' + CAST(Type_ID AS VARCHAR(10)) [text()]
                         FROM Prod_TypeTable 
                         WHERE Prod_IDM = t.Prod_IDM FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,2,' ') TypeID
               FROM Prod_TypeTable t
               GROUP BY Prod_IDM   )  As TypeList on TypeList.Prod_IDM = ProductTable.Prod_ID

我现在需要做的是将我之前的查询结果加入到类型表中,以便分别获取类型的名称。我怎么可能这样做?我的预期输出将是这样的

Prod_ID    |   Name    |  TypeName
-------        ----       ---------
   1       |   Name1   |  TypeName1,  TypeName3,  TypeName4,  TypeName5
   2       |   Name2   |  TypeName2,  TypeName3
   3       |   Name3   |  TypeName4
   4       |   Name4   |  TypeName5,  TypeName1
   5       |   Name5   |  TypeName4,  TypeName3,  TypeName2
   6       |   Name6   |  TypeName2,  TypeName3
   7       |   Name7   |  TypeName5 

2 个答案:

答案 0 :(得分:2)

组连接查询在SQL Server中很难表达,至少对于没有STRING_AGG函数的早期版本而言。诀窍是外部查询应该作用于其键具有要从加入一个或多个其他表聚合的值的表。在这种情况下,我们将ProductTable放在外面,然后汇总其他所有内容,为每个产品生成一个CSV类型列表。

SELECT
    p.Prod_ID,
    p.Name,
    TypeName = STUFF((
        SELECT ',' + t.TypeName
        FROM Prod_TypeTable pt
        INNER JOIN TypeTable t
            ON pt.Type_ID = t.Type_ID
        WHERE pt.Prod_IDM = p.Prod_ID
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM ProductTable p
ORDER BY p.Prod_ID;

enter image description here

Demo

答案 1 :(得分:0)

如果您使用的是SQL Server 2017+,我建议使用@ tim-biegeleisen提到的STRING_AGGSTRING_AGG连接字符串表达式的值并在它们之间放置分隔符值(不添加在字符串的末尾)。

SELECT
      p.Prod_ID,
      p.Name,
      TypeName = (
      SELECT STRING_AGG ( t.TypeName, ',')
          FROM Prod_TypeTable pt
          INNER JOIN TypeTable t
              ON pt.Type_ID = t.Type_ID
          WHERE pt.Prod_IDM = p.Prod_ID
    )
FROM ProductTable p
ORDER BY p.Prod_ID;

要了解有关SQL Server中查询连接的更多信息,我在下面的链接中写了一篇博客。 https://blog.vcillusion.co.in/understanding-the-grouped-concatenation-sql-server/