Registriert seit: 14. Apr 2008
3.006 Beiträge
Delphi 2009 Professional
|
AW: (SQL) Kochrezept: Zutatenliste nach erster Verwendung (jede Zutat nur einmal)
1. Sep 2022, 08:14
Nachtrag: hier ist eine leicht korrigierte Version http://sqlfiddle.com/#!18/bb18e/28/0
spot the bug
Code:
create table rezept (
rezeptid int,
optionalezutatid int,
bezeichnung nvarchar(80)
);
create table zutat (
zutatid int,
bezeichnung nvarchar(80)
);
create table zutaten (
rezeptid int,
zutatid int,
lfdnr int
);
insert into rezept values(111, null, 'Schokokuchen');
insert into rezept values(222, 6, 'Nusskuchen');
insert into zutat values (1,'Mehl');
insert into zutat values (2,'Schokoflocken');
insert into zutat values (3,'Butter');
insert into zutat values (4,'Zucker');
insert into zutat values (5,'Nüsse');
insert into zutat values (6,'Ahornsirup');
insert into zutaten values (111,1,1);
insert into zutaten values (111,2,2);
insert into zutaten values (111,3,3);
insert into zutaten values (111,4,4);
insert into zutaten values (111,2,5);
insert into zutaten values (222,1,1);
insert into zutaten values (222,5,2);
insert into zutaten values (222,3,3);
insert into zutaten values (222,4,4);
insert into zutaten values (222,5,5);
insert into zutaten values (222,6,6);
Code:
with CTE as (
select rezept.rezeptid, 'O' as optional, null as lfdnr, zutat.bezeichnung as bezeichnung
from rezept
join zutat on zutat.zutatid = rezept.optionalezutatid
union all
select rezept.rezeptid, 'P' as optional, zutaten.lfdnr, zutat.bezeichnung as bezeichnung
from zutaten
join zutat on zutat.zutatid = zutaten.zutatid
join rezept on rezept.rezeptid = zutaten.rezeptid
where lfdnr=(select min(lfdnr) from zutaten z where z.rezeptid=zutaten.rezeptid and z.zutatid=zutaten.zutatid)
and (rezept.optionalezutatid is null or zutaten.zutatid <> rezept.optionalezutatid)
)
select rezept.rezeptid,
(select concat(bezeichnung, ' ')
from cte
where cte.rezeptid = rezept.rezeptid
order by optional, lfdnr
for xml path(''))
from rezept
Alternativ mit string_agg:
Code:
with CTE as (
select rezept.rezeptid, 'O' as optional, null as lfdnr, zutat.bezeichnung as bezeichnung
from rezept
join zutat on zutat.zutatid = rezept.optionalezutatid
union all
select rezept.rezeptid, 'P' as optional, zutaten.lfdnr, zutat.bezeichnung as bezeichnung
from zutaten
join zutat on zutat.zutatid = zutaten.zutatid
join rezept on rezept.rezeptid = zutaten.rezeptid
where lfdnr=(select min(lfdnr) from zutaten z where z.rezeptid=zutaten.rezeptid and z.zutatid=zutaten.zutatid)
and (rezept.optionalezutatid is null or zutaten.zutatid <> rezept.optionalezutatid)
)
select rezept.rezeptid,
string_agg(cte.bezeichnung, ' ')
within group (order by optional, lfdnr)
from rezept
join cte on cte.rezeptid = rezept.rezeptid
group by rezept.rezeptid
http://sqlfiddle.com/#!18/bb18e/37/0
(ab MS SQL 2017)
Michael Justin
Geändert von mjustin ( 1. Sep 2022 um 08:25 Uhr)
Grund: Variante mit string_agg ergänzt
|