sql - 在 SQL View 中的列选择中使用左连接别名

标签 sql sql-server view

我正在努力在 SQL Server 中创建一个 View ,其中一列需要是来自不同表的逗号分隔值。例如,考虑下表 -

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),
)

示例数据

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)

我想要的是如图所示的东西

enter image description here

虽然我已经能够使用下面的脚本获得结果,但我有一种感觉,就性能而言,这不是最好的(当然不是唯一的)方法 -

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

我还尝试了下面的脚本 -

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

但它不会连接字符串并为每个技能返回单独的行,如下所示 -

enter image description here

那么,我对第一个脚本的假设正确吗?如果是这样,我缺少什么概念以及实现它的最有效方法是什么。

最佳答案

我会尝试使用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);

通过这种方式,优化器将调用 STUFF() 一次,而不是对外部查询返回的所有行进行调用。

关于sql - 在 SQL View 中的列选择中使用左连接别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55359877/

相关文章:

sql - DISTINCT 仅适用于一列

android - 带有布局的自定义 View

c# - MVC3 将字典<string,bool> 从 View 传递到 Controller

java - 使用预准备语句的变量列名

sql - Oracle查询以秒为单位的时差

c++ - 使用 ODBC 显式锁定和解锁表

当应用程序变为事件状态时,iOS 始终在起始页上

sql - 用于连接表的 Postgres 唯一多列索引

sql - 使用数据来命名列

java - 如何在 JBoss 中配置 SQL Server 数据源以使用特定的 Active Directory 用户进行连接?