springstil
Goto Top

MSSQL View Daten zusammenführen wenn X Gleich

Hallo zusammen,

ich habe eine View die sieht so aus:

SELECT
	f030.mcart,
	swkobj.wid,
	swktxt.kurz,
	swktxt.lang 
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)

Das klappt alles wunderbar. Nun möchte ich aber das der MCART nur einmal angezeigt wird, und das alle WID, Kurz und Lang einfach mit "," getrennt hintereinander steht.

Zur zeit sieht es so aus:

Mcart WID Kurz Lang
1119011-00 35 Kunstpflanze Kunstpflanze
1119011-00 36 Blume Blume

würde das aber gerne so haben:
Mcart WID Kurz Lang
1119011-00 35,36 Kunstpflanze, Blume Kunstpflanze, Blume

Wie kann ich das realisieren? Vielen dank face-smile

Content-Key: 1592169766

Url: https://administrator.de/contentid/1592169766

Printed on: April 26, 2024 at 02:04 o'clock

Mitglied: 149569
149569 Dec 06, 2021 updated at 09:37:47 (UTC)
Goto Top
EIn GROUP BY und Mergen der Werte mittels Aggregatfunktion sollte dir helfen, etwa so
SELECT
	f030.mcart,
	CONCAT_WS(",", swkobj.wid) as WID,  
	CONCAT_WS(",", swktxt.kurz) as Kurz,  
	CONCAT_WS(",", swktxt.lang) as Lang  
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
GROUP BY 
        f030.mcart;
https://www.w3schools.com/sql/sql_groupby.asp
https://www.sqlservertutorial.net/sql-server-string-functions/sql-server ...
Member: Springstil
Springstil Dec 06, 2021 at 10:12:58 (UTC)
Goto Top
Zitat von @149569:

EIn GROUP BY und Mergen der Werte mittels Aggregatfunktion sollte dir helfen, etwa so
> SELECT
> 	f030.mcart,
> 	CONCAT_WS(",", swkobj.wid) as WID,  
> 	CONCAT_WS(",", swktxt.kurz) as Kurz,  
> 	CONCAT_WS(",", swktxt.lang) as Lang  
> FROM
> 	dbo.swkobj
> 	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
> 	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
> WHERE
> 	swktxt.spr = 'ger'   
> 	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
> GROUP BY 
>         f030.mcart;
> 
https://www.w3schools.com/sql/sql_groupby.asp
https://www.sqlservertutorial.net/sql-server-string-functions/sql-server ...

Danke das Concat_ws kannte ich so nicht. Allerdings bekomme ich die Meldung:

Meldung 195, Ebene 15, Status 10, Zeile 3
CONCAT_WS wird nicht als Name einer integrierten Funktion erkannt.
Mitglied: 149569
149569 Dec 06, 2021 updated at 10:24:54 (UTC)
Goto Top
CONCAT_WS wird nicht als Name einer integrierten Funktion erkannt.
Hast du wohl einen alten SQL Server (älter als 2017)
https://docs.microsoft.com/en-us/sql/t-sql/functions/concat-ws-transact- ...
Für die siehe die Alternativen zu CONCAT_WS
STRING_AGG
https://stackoverflow.com/questions/19432370/concat-ws-for-sql-server
Member: Springstil
Springstil Dec 06, 2021 at 10:32:12 (UTC)
Goto Top
Zitat von @149569:

CONCAT_WS wird nicht als Name einer integrierten Funktion erkannt.
Hast du wohl einen alten SQL Server (älter als 2017)
https://docs.microsoft.com/en-us/sql/t-sql/functions/concat-ws-transact- ...
Für die siehe die Alternativen zu CONCAT_WS
STRING_AGG
https://stackoverflow.com/questions/19432370/concat-ws-for-sql-server

Habe ich schon versucht. Ich kriege die Daten nur nicht anständig Gruppiert. Gebe ich im Group By nur die f030.mcart an, möchte er das ich die anderen auch noch einfüge, wenn ich allerdings alle mit angebe Gruppiert er diese nicht mehr
Mitglied: 149569
149569 Dec 06, 2021 updated at 10:55:47 (UTC)
Goto Top
Klappt hier im Test aber problemlos, welche SQL Server Version nutzt du denn überhaupt ..?
Gebe ich im Group By nur die f030.mcart an, möchte er das ich die anderen auch noch einfüge, wenn ich allerdings alle mit angebe Gruppiert er diese nicht mehr
Nee, das sagt er nur weil er die Aggregations-Funktion auf deinem Server wohl nicht findet, denn alle anderen Spalten sind ja oben korrekt mit einer Aggregatsfunktion versehen, im GROUP BY muss nur die Spalte stehen nach der man gruppieren möchte.
Member: Springstil
Springstil Dec 06, 2021 at 10:59:21 (UTC)
Goto Top
Zitat von @149569:

Klappt hier im Test aber problemlos, welche SQL Server Version nutzt du denn überhaupt ..?
Gebe ich im Group By nur die f030.mcart an, möchte er das ich die anderen auch noch einfüge, wenn ich allerdings alle mit angebe Gruppiert er diese nicht mehr
Nee, das sagt er nur weil er die Aggregations-Funktion auf deinem Server wohl nicht findet, denn alle anderen Spalten sind ja oben korrekt mit einer Aggregatsfunktion versehen, im GROUP BY muss nur die Spalte stehen nach der man gruppieren möchte.

Wir nutzen 2016 als SQL.

Wenn ich
SELECT
	f030.mcart,
	CONCAT(
	COALESCE(f030.mcart + ' - ', ''),  
	COALESCE(swktxt.wid + ' - ', '') ,  
	COALESCE(swktxt.lang + ' - ', '') ) as Test  
	
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
GROUP BY
f030.mcart

schreibe meldet er:
[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Die dbo.swktxt.wid-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion und nicht in der GROUP BY-Klausel enthalten ist. (8120)
[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Die dbo.swktxt.lang-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion und nicht in der GROUP BY-Klausel enthalten ist. (8120)
[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Die dbo.swktxt.lang-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion und nicht in der GROUP BY-Klausel enthalten ist. (8120)

Nehme ich den Group By raus oder füge die anderen beiden hinzu bekomme ich das zwar ausgegeben, allerdings habe ich trotzdem Doppelte Artikelnummern.
Mitglied: 149569
149569 Dec 06, 2021 updated at 11:21:46 (UTC)
Goto Top
Zitat von @Springstil:
Wir nutzen 2016 als SQL.
Dann ist es klar, dort gibt es oben genutzten Aggregats-Funktionen nicht
In dem Fall siehe Workaround hier mit STUFF
Rolling up multiple rows into a single row and column for SQL Server data
Nachmachen und freuen face-wink.
Member: ukulele-7
ukulele-7 Dec 06, 2021 updated at 11:42:17 (UTC)
Goto Top
stuff() mit FOR XML PATH ist hier zum einen die gängige Methode um in MSSQL (2016 und früher) Zeichenketten zu aggregieren und zum Anderen bietet es dir noch die Möglichkeit deine Spalten kurz und lang zu kombinieren wie du es gerne hättest. Beispiel:
WITH t AS (
SELECT
	f030.mcart,
	swkobj.wid,
	swktxt.kurz,
	swktxt.lang 
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
	)
SELECT	t.mcart,
		t.wid,
		stuff((	SELECT	'; ' + (	CASE  
									WHEN	t1.kurz != t1.lang
									THEN	t1.kurz + '(' + t1.lang + ')'  
									ELSE	t1.kurz
									END )
				FROM	t t1
				WHERE	t1.mcart = t.mcart
				AND		t1.wid = t.wid
				FOR XML PATH ('')),1,1,'') AS tolles_stuff  
FROM	t
GROUP BY t.mcart,t.wid
Member: Springstil
Springstil Dec 06, 2021 at 12:20:57 (UTC)
Goto Top
Zitat von @ukulele-7:

stuff() mit FOR XML PATH ist hier zum einen die gängige Methode um in MSSQL (2016 und früher) Zeichenketten zu aggregieren und zum Anderen bietet es dir noch die Möglichkeit deine Spalten kurz und lang zu kombinieren wie du es gerne hättest. Beispiel:
WITH t AS (
> SELECT
> 	f030.mcart,
> 	swkobj.wid,
> 	swktxt.kurz,
> 	swktxt.lang 
> FROM
> 	dbo.swkobj
> 	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
> 	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
> WHERE
> 	swktxt.spr = 'ger'   
> 	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
> 	)
> SELECT	t.mcart,
> 		t.wid,
> 		stuff((	SELECT	'; ' + (	CASE  
> 									WHEN	t1.kurz != t1.lang
> 									THEN	t1.kurz + '(' + t1.lang + ')'  
> 									ELSE	t1.kurz
> 									END )
> 				FROM	t t1
> 				WHERE	t1.mcart = t.mcart
> 				AND		t1.wid = t.wid
> 				FOR XML PATH ('')),1,1,'') AS tolles_stuff  
> FROM	t
> GROUP BY t.mcart,t.wid

Danke das funktioniert mit den Beschreibungen ja gut, allerdings brauche ich dazu noch die WID zusammen. Allerdings bekomme ich es nicht umgebaut trotz den Anleitungen..
Member: ukulele-7
ukulele-7 Dec 07, 2021 updated at 09:19:49 (UTC)
Goto Top
Welches Format hat denn deine WID? Was soll am Ende raus kommen? Eventuell sowas hier:
WITH t AS (
SELECT
	f030.mcart,
	swkobj.wid,
	swktxt.kurz,
	swktxt.lang 
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
	)
SELECT	t.mcart,
		t.wid,
		stuff((	SELECT	'; ' + cast(t1.wid AS VARCHAR(20)) + ' ' +  
								(	CASE
									WHEN	t1.kurz != t1.lang
									THEN	t1.kurz + '(' + t1.lang + ')'  
									ELSE	t1.kurz
									END )
				FROM	t t1
				WHERE	t1.mcart = t.mcart
				AND		t1.wid = t.wid
				FOR XML PATH ('')),1,1,'') AS tolles_stuff  
FROM	t
GROUP BY t.mcart,t.wid
Das ist aber ziemlich geraten.
Member: Springstil
Springstil Dec 15, 2021 at 07:30:54 (UTC)
Goto Top
Hallo ukulele-7,

sorry für die späte Antwort wir hatten ein Tragischen zwichenfall in der Familie.

Die WID sind immer nur zahlen 2 bis 3 stellig. Diese würde ich gerne genau so zusammen gefasst haben wie die Bezeichnungen.

Leider klappt das mit dem Code auch nicht da er auch nur die Bezeichnungen zusammen packt und nicht auch die WID. Dadurch habe ich wieder doppelte Artikelnummern.
Member: ukulele-7
Solution ukulele-7 Dec 15, 2021 at 07:43:19 (UTC)
Goto Top
Kein Problem manchmal gibt es Wichtigeres.

Der SQL Code ist jetzt auch nicht so komplex wenn man das mal gemacht hat. Ich kenne allerdings die Details nicht wie Datentyp der Spalten etc. Deinem letzten Satz entnehme ich das der Code zumindest ein Ergebnis liefert, ich versuche mal das richtig anzupassen:
WITH t AS (
SELECT
	f030.mcart,
	swkobj.wid,
	swktxt.kurz,
	swktxt.lang 
FROM
	dbo.swkobj
	LEFT JOIN dbo.swktxt ON swkobj.wid = swktxt.wid
	LEFT JOIN dbo.f030 ON swkobj.refkey = f030.key_1 
WHERE
	swktxt.spr = 'ger'   
	AND swkobj.wid NOT IN (41,119,120,122,124,125,127,130,131,132,133,134,135,136,137,138,140,141,142,143,144,145,147,148,150,151,152,153,154,157,158,159,162,163,164,165,166,187,188,189,191,192,193,194,195,196,197,202,203,204,205,206,207,208,209,214,215,219,220,235,243,244,121,242)
	)
SELECT	t.mcart,
		stuff((	SELECT	'; ' + cast(t1.wid AS VARCHAR(10)) + ' ' +  
								(	CASE
									WHEN	t1.kurz != t1.lang
									THEN	t1.kurz + '(' + t1.lang + ')'  
									ELSE	t1.kurz
									END )
				FROM	t t1
				WHERE	t1.mcart = t.mcart
				FOR XML PATH ('')),1,1,'') AS tolles_stuff  
FROM	t
GROUP BY t.mcart