从 SQL 服务器中的相关表中订购逗号分隔的列值

Ordering comma separated column values from related tables in SQL server

我正在使用 SQL 服务器。我想查询下面提到的要求。我在 SQL 处于初级水平 我有两个表如下所示:

Table: 汽车

Id CarName Company LaunchYear
1 Audi Q7 Audi 2022
2 Ford GT Ford 2021

Table: 车型

TypeId CarId Colour PetrolRate DieselRate ElectricRate
1 1 PLATINUM 10000 9000 11000
2 1 GOLD 9500 8500 10500
3 1 SILVER 9250 8250 10250

我需要在单行中输出独特的汽车。

它必须有基于颜色的逗号分隔值。

颜色值必须按字母升序排列,并且费率必须与颜色对齐。

我尝试了下面的查询,但我得到的是一辆车的多行:

select * 
from Car c
left join CarType ct on ct.CarId= c.Id
where c.Id = 1

请参考下面要求的输出:

输出

CarId CarName Company LaunchYear Colours PetrolRates DieselRates ElectricRates
1 Audi Q7 Audi 2022 GOLD,PLATINUM,SILVER 9500,10000,9250 8500,9000,8250 10500,11000,10250

回答接受原因:

我已经接受了使用 XML PATH 的解决方案,因为我有 SQL Server 2016。

注意:String_AGG() 适用于 SQL Server 2017 及更高版本。与它一起列出的解决方案也很合适。 (只能采纳一个答案:))

我们可以使用 STRING_AGG( ~ , ',')WITHIN GROUP (ORDER BY TypeId) 制作逗号分隔列表,以确保不同值的顺序正确。

create table cars (id int, carName varchar(25), Company varchar(25), LaunchYear int)
insert into cars values (1,'Audo Q7','Audi',2022),(2,'Ford GT','Ford',2021);
create table carType(TypeId int,CarId   int,Colour  varchar(10),PetrolRate  int,DieselRate  int,ElectricRate int);
insert into carType values
(1, 1,  'PLATINUM',10000,9000,  11000),
(2, 1,  'GOLD'    ,9500 ,8500,  10500),
(3, 1,  'SILVER'  ,9250 ,8250,  10250);

select
  c.id,
  c.carName,
  c.Company,
  c.LaunchYear,
  string_agg( Colour ,',') WITHIN GROUP (ORDER BY TypeId) Colour,
  string_agg( PetrolRate,',') WITHIN GROUP (ORDER BY TypeId) PetrolRate,
  string_agg( DieselRate,',') WITHIN GROUP (ORDER BY TypeId) DieselRate,
  string_agg( ElectricRate,',') WITHIN GROUP (ORDER BY TypeId) ElectricRate
from cars c
left join carType t
on c.id = t.carID
group by
  c.id,
  c.carName,
  c.Company,
  c.LaunchYear
GO
 id | carName | Company | LaunchYear | Colour               | PetrolRate      | DieselRate     | ElectricRate     
 -: | :------ | :------ | ---------: | :------------------- | :-------------- | :------------- | :----------------
  1 | Audo Q7 | Audi    |       2022 | PLATINUM,GOLD,SILVER | 10000,9500,9250 | 9000,8500,8250 | 11000,10500,10250
  2 | Ford GT | Ford    |       2021 | null                 | null            | null           | null             
 

db<>fiddle here

这可以使用 FOR XML PATH 字符串函数实现,因为 sql 服务器 2005

select t1.id, t1.CarName, t1.Company, t1.LaunchYear, t2.Colours, t2.PetrolRates, t2.DieselRates, t2.ElectricRates
from Car t1
inner join
    (select  CarId
       ,stuff((SELECT ', ' + cast(Colour AS varchar(50)) [text()]
         from CarType 
         where CarId = t.CarId
         for xml path(''), type)
        .value('.','NVARCHAR(MAX)'),1,2,' ') Colours
        ,stuff((SELECT ', ' + cast(PetrolRate AS varchar(50)) [text()]
         from CarType 
         where CarId = t.CarId
         for xml path(''), type)
        .value('.','NVARCHAR(MAX)'),1,2,' ') PetrolRates
        ,stuff((SELECT ', ' + cast(DieselRate AS varchar(50)) [text()]
         from CarType 
         where CarId = t.CarId
         for xml path(''), type)
        .value('.','NVARCHAR(MAX)'),1,2,' ') DieselRates
        ,stuff((SELECT ', ' + cast(ElectricRate AS varchar(50)) [text()]
         from CarType 
         where CarId = t.CarId
         for xml path(''), type)
        .value('.','NVARCHAR(MAX)'),1,2,' ') ElectricRates
    from CarType t
    group by CarId) as t2 on t2.CarId = t1.id