【问题标题】:SQL Server : one to many select query [duplicate]SQL Server:一对多选择查询[重复]
【发布时间】:2017-10-22 12:25:21
【问题描述】:

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

第一个表:

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

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

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

是否可行,如果可行,合适的方法是什么?欢迎任何帮助!

【问题讨论】:

    标签: sql sql-server select inner-join


    【解决方案1】:

    您可以为此使用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 |
    

    【讨论】:

    • @GordonLinoff 谢谢,是的,你是对的。
    • 谢谢,它工作正常。如何更新以排除那些没有车辆的人?因为到目前为止,我在 Vehicles 上获得了所有带有 null 的人(如果他们不拥有车辆)。谢谢。
    【解决方案2】:

    最新版本的 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

    【讨论】:

    • 谢谢,但很遗憾我使用的是旧版本的 SQL Server。
    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    相关资源
    最近更新 更多