I am using SQL server. I would like to have a query for below mentioned requirement. I am at Beginner level in SQL I have two tables as shown below:
Table: Car
Id | CarName | Company | LaunchYear |
---|---|---|---|
1 | Audi Q7 | Audi | 2022 |
2 | Ford GT | Ford | 2021 |
Table: CarType
TypeId | CarId | Colour | PetrolRate | DieselRate | ElectricRate |
---|---|---|---|---|---|
1 | 1 | PLATINUM | 10000 | 9000 | 11000 |
2 | 1 | GOLD | 9500 | 8500 | 10500 |
3 | 1 | SILVER | 9250 | 8250 | 10250 |
I require the output in a single row for unique car.
It must have comma separated values of rates based on their colours.
The value of colours must be ordered by alphabetically ascending and the rates must be aligned with the colours.
I tried below query but I am getting multiple rows for a single car:
select *
from Car c
left join CarType ct on ct.CarId= c.Id
where c.Id = 1
Please refer below required output:
Output
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 |
CodePudding user response:
We can use STRING_AGG( ~ , ',')
to make a comma seperated list with WITHIN GROUP (ORDER BY TypeId)
to be sure that the different values are in the right order.
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
CodePudding user response:
This is achievable using FOR XML PATH
string function since sql server 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