【问题标题】:SQL Server 2008: many-to-many relationship: Concatenation in SELECT query [duplicate]SQL Server 2008:多对多关系:SELECT查询中的连接[重复]
【发布时间】:2019-04-13 21:05:50
【问题描述】:

有3张桌子:

  1. 项目
  2. 工具
  3. LinkProjectTool

我需要一个查询来列出 Project 表中的所有内容以及一个名为 ProjectTools 的额外列。此列应包含一个逗号分隔的字符串,其中包含属于每个项目的所有工具名称。

数据是:

项目

ID  Name        Client
------------------------
0   table       Anna
1   chair       Bobby
2   workbench   James
3   window      Jenny
4   shelves     Matthew

表格工具

ID  Name
------------------------
0   hammer
1   measuring tape
2   pliers
3   scissors
4   spanner
5   saw
6   screwdriver

表格LinkProjectTool

IDProject   IDTool
-------------------
0       0
0       3
2       1
2       4
2       5

结果应该是:

ID  Name        Client      ProjectTools
-------------------------------------------------------------
0   table       Anna        hammer, scissors
1   chair       Bobby
2   workbench   James       measuring tape, spanner, saw
3   window      Jenny
4   shelves     Matthew

以下是我用来创建这些表的查询:

CREATE TABLE [dbo].[Project]
(
    [ID] [int] NOT NULL,
    [Name] [nvarchar](15) NOT NULL,
    [Client] [nvarchar](15) NULL
)

INSERT INTO [dbo].[Project]
       (ID, Name, Client)
     VALUES
       (0, 'table', 'Anna'),
       (1, 'chair', 'Bobby'),
       (2, 'workbench', 'James'),
       (3, 'window', 'Jenny'),
       (4, 'shelves', 'Matthew')

CREATE TABLE [dbo].[Tool](
    [ID] [tinyint] IDENTITY(0,1) NOT NULL,
    [Name] [nvarchar](30) NULL,
 CONSTRAINT [PK_Tool] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO [dbo].Tool
       (Name)
     VALUES
       ('hammer'),
       ('measuring tape'),
       ('pliers'),
       ('scissors'),
       ('spanner'),
       ('saw'),
       ('screwdriver')

CREATE TABLE [dbo].LinkProjectTool
(
    [IDProject] [int] NOT NULL,
    [IDTool] [tinyint] NULL
)

INSERT INTO [dbo].LinkProjectTool
    (IDProject, IDTool)
     VALUES
       (0, 0),
       (0, 3),
       (2, 1),
       (2, 4),
       (2, 5)

你能帮忙吗?

谢谢。

【问题讨论】:

  • 周围有很多例子。但是 - 看到你精心设计的minimal reproducible example - 我想你已经投入了相当长的时间。为我的问题 +1...

标签: sql sql-server tsql many-to-many concatenation


【解决方案1】:

您可以将STUFF 函数与FOR XML 一起使用(有关它们如何工作的更详细说明,请参阅this answer)。

假设您希望项目工具用逗号和空格分隔,您可以使用以下查询:

SELECT DISTINCT p.ID, p.Name, p.Client,
    ProjectTools = STUFF((
        SELECT ', ' + t.Name
        FROM Tool t
        WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID

【讨论】:

  • 虽然这个答案还可以,但它是 1)重复且更重要:2)您确实应该了解自己的代码。 STUFF() 与这里的 分组连接 无关。这是由带有FOR XML PATH 的子选择提供的。这个函数STUFF()没有别的意思,就是去掉前面的逗号+空格...
猜你喜欢
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
相关资源
最近更新 更多