简体   繁体   English

在SQL视图中的列选择中使用左连接别名

[英]Use Left Join Alias in Column Select in SQL Views

I am working on creating a view in SQL server one of the columns for which needs to be a comma separated value from a different table. 我正在努力在SQL服务器中创建一个视图,其中一列需要是来自不同表的逗号分隔值。 Consider the tables below for instance - 以下表为例 -

CREATE TABLE Persons
(
    Id INT NOT NULL PRIMARY KEY,
    Name VARCHAR (100)
)

CREATE TABLE Skills
(
    Id INT NOT NULL PRIMARY KEY,
    Name VARCHAR (100),
)

CREATE TABLE PersonSkillLinks
(
    Id INT NOT NULL PRIMARY KEY,
    SkillId INT FOREIGN KEY REFERENCES Skills(Id),
    PersonId INT FOREIGN KEY REFERENCES Persons(Id),
)

Sample data 样本数据

INSERT INTO Persons VALUES
(1, 'Peter'),
(2, 'Sam'),
(3, 'Chris')


INSERT INTO Skills VALUES
(1, 'Poetry'),
(2, 'Cooking'),
(3, 'Movies')

INSERT INTO PersonSkillLinks VALUES
(1, 1, 1),
(2, 2, 1),
(3, 3, 1)

What I want is something like shown in the image 我想要的是图像中显示的内容

在此输入图像描述

While I have been able to get the results using the script below, I have a feeling that this is not the best (and certainly not the only) way to do as far as performance goes - 虽然我已经能够使用下面的脚本获得结果,但我觉得这不是最好的(当然也不是唯一的)方法,就性能而言 -

CREATE VIEW vwPersonsAndTheirSkills
AS
    SELECT p.Name,
    ISNULL(STUFF((SELECT ', ' + s.Name FROM Skills s JOIN PersonSkillLinks psl ON s.Id = psl.SkillId WHERE psl.personId = p.Id FOR XML PATH ('')), 1, 2, ''), '') AS Skill
    FROM Persons p 
GO

I also tried my luck with the script below - 我也试过下面的脚本运气 -

CREATE VIEW vwPersonsAndTheirSkills
AS
 SELECT p.Name,
 ISNULL(STUFF((SELECT ', ' + skill.Name FOR XML PATH ('')), 1, 2, ''), '') AS Skill
 FROM persons p
 LEFT JOIN 
 (
    SELECT s.Name, psl.personid FROM Skills s
    JOIN PersonSkillLinks psl ON s.Id = psl.SkillId
 ) skill ON skill.personId = p.Id

GO

but it is not concatenating the strings and returning separate rows for each skill as shown below - 但它没有连接字符串并为每个技能返回单独的行,如下所示 -

在此输入图像描述

So, is my assumption about the first script correct? 那么,我对第一个脚本的假设是正确的吗? If so, what concept am I missing about it and what should be the most efficient way to achieve it. 如果是这样,我错过了什么概念,以及实现它的最有效方法。

I would try with APPLY : 我会尝试使用APPLY

SELECT p.Name, STUFF(ss.skills, 1, 2, '') AS Skill
FROM Persons p OUTER APPLY
     (SELECT ', ' + s.Name 
      FROM Skills s JOIN 
           PersonSkillLinks psl 
           ON s.Id = psl.SkillId 
      WHERE psl.personId = p.Id 
      FOR XML PATH ('')
     ) ss(skills);

By this way, optimizer will call STUFF() once not for all rows returned by outer query. 通过这种方式,优化器将为外部查询返回的所有行调用一次STUFF()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM