SQL Server:一对多选择查询

时间:2017-10-22 12:25:22

标签: sql sql-server select inner-join

我有两张表,逻辑上与一对一相关。

第一张表:

CREATE TABLE Persons 
(
    ID int NOT NULL PRIMARY KEY,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255), 
    Age int
);

第二张表:

CREATE TABLE Vehicles 
(
    Brand varchar(50), 
    PersonID int,

    FOREIGN KEY(PersonID) REFERENCES Persons(ID)
);

我的方法是列出每个人和这个人拥有的车辆。

我设法做的事情:

SELECT LastName, brand 
FROM vehicles
INNER JOIN Persons ON Persons.ID = PersonID
ORDER BY LastName ASC

不幸的是,这不是我想要做的,即显示每个人一次,并在其旁边显示车辆的列表,用于前:

User1 | kia, ford, jeep
User2 | ferrari, harley

它是否可行,如果是,那么适当的方式是什么?欢迎任何帮助!

2 个答案:

答案 0 :(得分:3)

您可以将FOR XMLSUFF一起使用:

SELECT FirstName, LastName,
STUFF((
    SELECT ', ' + v.Brand
    FROM vehicles as v
    WHERE v.PersonID = p.ID
    FOR XML PATH (''))
  ,1,2,'') AS Vehicles
FROM Persons AS p;

结果:

| FirstName | LastName |        Vehicles |
|-----------|----------|-----------------|
|     User1 |    user1 | Ford, kia, jeep |
|     User2 |    User2 |  ferrri, harley |

答案 1 :(得分:1)

最新版本的SQL Server(SQL Server 2017)最终内置了此功能。所以你可以这样做:

SELECT p.LastName,
       STRING_AGG(v.brand, ', ') WITHIN GROUP (ORDER BY v.brand) as vehicles
FROM Persons p JOIN
     vehicles v
     ON p.ID = v.PersonID
GROUP BY p.ID, p.LastName;

如果您有一个包含多个表的查询,我建议您始终使用表别名和限定列名。

如果您希望包含没有车辆的人,请使用LEFT JOIN