2013-07-11 30 views
69

SQL Server'da Group_concat işlevini kullanamayacağımızı biliyorum ama burada bir sorunum var. Group_Concat sorguma ihtiyacım var. Google biraz mantık buldu ama mümkün değil doğru it.My sql sorgusu Bu beni Sadece o maskid, maskname, schoolid ilk 3 sırayı bakmaksql sunucusunda group_concat ile bir sorgu oluşturma

enter image description here

gibi sonuçlanır verir

select m.maskid,m.maskname,m.schoolid,s.schoolname, 
md.maskdetail 
from tblmask m join school s on s.id = m.schoolid 
join maskdetails md on m.maskid = md.maskid 
order by m.maskname ; 

olduğunu schoolname aynıdır ama çok istiyorum farklı maskdetail olduğunu birine Son sütun hangi maskid başına tüm maskectails içerebilir ve bunun için satır.

bunun için bir sorgu yaparken bu yüzden

enter image description here

Ve benzeri benim çıkış on.So bana yardım edin istiyorum.

Şimdiden teşekkürler.

+1

Bu, * [* STRING_AGG '] eklendiğinden beri SQL Server 2005 ile ilgili sorgunun bir kopyası * (* https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql) SQL Server 2017'ye, bu yüzden yeni bir SQL Server ile kutsanmışsanız, bunun içine bakmak isteyebilirsiniz. –

cevap

92

Sorgu:

SELECT 
     m.maskid 
    , m.maskname 
    , m.schoolid 
    , s.schoolname 
    , maskdetail = STUFF((
      SELECT ',' + md.maskdetail 
      FROM dbo.maskdetails md 
      WHERE m.maskid = md.maskid 
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 
FROM dbo.tblmask m 
JOIN dbo.school s ON s.ID = m.schoolid 
ORDER BY m.maskname 

bilgiye:

String Aggregation in the World of SQL Server

+0

hmmm @Devart'ı görüntüleyebildiğim gibi iç birleştirme sonucu verebildiğim ... böylece tüm kopyaları bir araya getirmek için m.maskid , m.maskname , m.schoolid , s.schoolname bir gruba ihtiyacımız var –

+5

'tblmask' -' maskdetails' = '1 'den çok' 'arasında bir ilişki vardır, bu nedenle kayıtların kopyaları burada olmamalıdır. – Devart

+0

'PATH (''), TYPE 've' .value ('. ',' NVARCHAR (MAX) ') 'kullanmanın sebebi burada,' AmitSingh'ın asnwer'ındaki gibi basit 'PATH (' ')' nin aksine ? Varyantınız, daha ağır yürütme planı gibi bir yol katıyor, maliyeti haklı çıkarmak için gizli bir avantajı var mı? Eğer değilse, kabul edildiğinden ve en iyisi olması gerektiği için cevabınızı düzeltir veya değiştirir misiniz? – pvgoran

19
Select 
     A.maskid 
    , A.maskname 
    , A.schoolid 
    , B.schoolname 
    , STUFF((
      SELECT ',' + T.maskdetail 
      FROM dbo.maskdetails T 
      WHERE A.maskid = T.maskid 
      FOR XML PATH('')), 1, 1, '') as maskdetail 
FROM dbo.tblmask A 
JOIN dbo.school B ON B.ID = A.schoolid 
Group by A.maskid 
    , A.maskname 
    , A.schoolid 
    , B.schoolname 
+4

+1. Bu arada GROUP GROUP'a ihtiyaç yok. – Devart

5

aşağıda sorguyu çalıştırın, sizin durumda STUFF ve GROUP BY gerektiriyor :

+3

STUFF ilk virgülü şerit için gereklidir, sizin davanızda bir virgül –

6

Buda

CREATE FUNCTION [dbo].[FunctionName] 
(@MaskId INT) 
RETURNS Varchar(500) 
AS 
BEGIN 

    DECLARE @SchoolName varchar(500)       

    SELECT @SchoolName =ISNULL(@SchoolName ,'')+ MD.maskdetail +', ' 
    FROM maskdetails MD WITH (NOLOCK)  
    AND [email protected] 

    RETURN @SchoolName 

END 

Ve

sonra nihai sorgu

SELECT m.maskid,m.maskname,m.schoolid,s.schoolname, 
(SELECT [dbo].[FunctionName](m.maskid)) 'maskdetail' 
FROM tblmask m JOIN school s on s.id = m.schoolid 
ORDER BY m.maskname ; 

Not gibi olacak, Scalar-Valued FunctionMSSQL 2008
aşağıdaki gibi işlevini beyan kullanarak elde edilebilir:
You Tam tablo yapısını bilmediğim için işlevi değiştirmek zorunda kalabilir.

+0

ile biterse Ayrıca bakınız: https://gooroo.io/GoorooTHINK/Article/10001/Aggregate-String-Concatenation-in-SQL-Server-2012- gibi-stringagg-in-PostgreSQL/5122 # .Wif5rLaZMWo – Magne