4 messaggi dal 24 febbraio 2011
Ciao a tutti,
ho un problema con una query
sto cercando l'equivalente della funzione di MySQL GROUP_CONCAT in SQL Server.

Potreste darmi una mano?
4 messaggi dal 24 febbraio 2011
Grazie per la dritta.
Ho provato sia con SQL Server 2005 che con il 2008 è tutto funziona.
A me serve su SQL Server 2000, lì l'esito è stato negativo non riconosce le funzioni:

ROW_NUMBER()
PARTITION BY
e forse MAXRECURSION


potete darmi una mano?
Sono in grosse difficolta!
Grazie
2.198 messaggi dal 30 novembre 2001
quelle funzionalità nn sono supportate da sql2000
4 messaggi dal 24 febbraio 2011
C'è la possibilità di trasformare in una vista quello che hai segnalato:

http://explainextended.com/2010/06/21/group_concat-in-sql-server/


P.S. Usando Sql SERVER 2008.

Ti ringrazio anticipatamente
1.976 messaggi dal 27 luglio 2005
Contributi
salve,
la cosa e' "parzialmente" sostituibile in SQL Server 2000, ad esempio utilizzando la "concatenzazione" implicita di una variabile di tipo "carattere", quindi aggiungendo l'estrazione di ogni riga al valore gia' "raccolto" similarmente a
SET NOCOUNT ON;
GO
USE tempdb;
GO
CREATE TABLE dbo.t1 (
  Id int NOT NULL PRIMARY KEY,
  Data varchar(20) NOT NULL
  );
CREATE TABLE dbo.t2 (
  Id int NOT NULL IDENTITY PRIMARY KEY,
  IdT int NOT NULL
    CONSTRAINT FK_t2$has$t1 FOREIGN KEY
      REFERENCES dbo.t1 (Id),
  Data varchar(10) NOT NULL
  );
GO
INSERT INTO dbo.t1 VALUES (1, 'header1');
INSERT INTO dbo.t1 VALUES (2, 'header2');
INSERT INTO dbo.t1 VALUES (3, 'header3');
INSERT INTO dbo.t1 VALUES (4, 'empty');

INSERT INTO dbo.t2 VALUES (1, 'row1.1');
INSERT INTO dbo.t2 VALUES (2, 'row2.1');
INSERT INTO dbo.t2 VALUES (2, 'row2.2');
INSERT INTO dbo.t2 VALUES (3, 'row3.1');
INSERT INTO dbo.t2 VALUES (3, 'row3.2');
INSERT INTO dbo.t2 VALUES (3, 'row3.3');
GO
CREATE FUNCTION dbo.udf_GetT2$Concat (
  @IdT1 int
  ) RETURNS varchar(1000)
AS BEGIN
  DECLARE @value varchar(1000);
  SET @value = '';
  SELECT @value = @value + CASE WHEN DATALENGTH(@value) <> 0 THEN ',' ELSE '' END + t2.Data
    FROM dbo.t2 t2
    WHERE t2.IdT = @IdT1
    ORDER BY t2.Data;
  RETURN (@value);
END;
GO
SELECT t1.Id, t1.Data, dbo.udf_GetT2$Concat(t1.Id) AS [Concat]
  FROM dbo.t1 t1
  ORDER BY t1.Id
GO
DROP FUNCTION dbo.udf_GetT2$Concat;
DROP TABLE dbo.t2, dbo.t1;
GO
--<---------
Id          Data                 Concat
----------- -------------------- ---------------------
1           header1              row1.1
2           header2              row2.1,row2.2
3           header3              row3.1,row3.2,row3.3
4           empty                


dove la variabile @value deve essere dimensionata sufficientemente "grande" da poter ospitare la concatenazione dei risultati.. questo dimensionamento non puo' eccedere gli 8000 caratteri o 4000 unicode, a seconda venga utilizzato il tipo di dato carattere "normale" (varchar) o carattere nazionale (nvarchar)...
sappi pero' che questa espressione puo' dare risultati non corretti in termini di ordinamento... malgrado la funzione utente espliciti un'estrazione "... ORDER BY t2.Data;", come ben sai l'ordinamento di un'estrazione e' "l'ultima parte" eseguita in una query di estrazione.. a dire il vero non fa neanche parte della query stessa, nel senzo che:
tipicamente, una query SQL viene eseguita come segue, almeno in teoria, visto che ogni produttore poi chiaramente cerca di ottimizzare sia le operazioni preliminari che l'insieme generale al fine di migliare le prestazioni...

-) iniziando dalla clausola FROM, viene construita una working table che tenga in considerazione tutte le tabelle conivolte, quindi JOIN, unioni, intersezioni eccetera.. l'aliasing di tabelle e SUBQUERY consente successivamente di "nominare" tale risultato..

-) la clausola WHERE rimuove le righe che non soddisfino i filtri impostati, cioe' che non ritornino, in base al filtro di WHERE, un risultato VERO (true), per cui falso e unknown vengono scartati.. tale clausola viene applicata al working set derivante dalla esplosione della clausola FROM..

-) l'eventuale presenza di una clausola GROUP BY provvede alla produzione degli aggregati riducendo ognuno di essi ad una singola riga, rimpiazzando la working table con la nuova aggragata.. le righe di una tale tabella devono avere caratteristiche di aggregazione, qualie un raggruppamento di colonna, una statistica sul raggruppamento (tipo le funzioni built'in di aggregazione), una funzione ovvero un'espressione composta dai tre elementi di cui sopra..

-) l'eventuale clausola opzionale HAVING, applicata alla working table raggruppata; qualora non fosse presente la clausola GROUP BY clause, l'intera working table viene trattata come un unico raggruppamento...

-) esplosione della proiezione con riferimento alla SELECT list, qundi dopo tutte le operazioni preliminari di selezione/intersezione/unione... le operazioni di algebra relazionale avvengono precedentemente.. l'utilizzo di alias di colonna avviene a livello atomico, sempre dopo l'esecuzione della proiezione, quindi non sono utilizzabili ad esempio nel filtro di WHERE...
l'eventuale presenza di DISTINCT provvede all'eliminazione di righe
duplicate..

-) subquery innestate utilizzano il normale scope dei linguaggi strutturali, per cui le piu' interne possono fare riferimento a colonne delle esterne che le contengono..

-) finalmente la clausola ORDER BY, che non e' piu' parte della query in quanto tale, ma di un'operazione di cursore; il risultato della query viene passato al cursore che porvvede all'ordinamento

visto che come visto lo storage engine, invece, puo' ritornare le righe che soddisfano il filtro di WHERE in qualsiasi ordine, ad esempio grazie alla parallelizzazione dell'operazione di estrazione, e che "l'aggregazione" sulla variabile temporanea utilizzata e' un'operazione "precedente" all'ordinamento eseguito solo successivamente, potenzialmente per t1.Id = 3 potresti ottenere il risultato "row3.3,row3.1,row3.2" ovvero una qualsiasi delle 9 possibilita' di aggregazione.. cio' non toglie che in SQL Server 2000 restava l'unica possibilita' di ottenere un risultato simile a quello richiesto..
saluti

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php
4 messaggi dal 24 febbraio 2011
Grazie per l'aiuto che mi avete dato.
Sei dei guru!!!

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.