2013-07-11 13 views
69

私はGroup_concat機能を使用できないことを知っていますが、ここで私はGroup_Concatが必要な問題が1つあります。正しいit.MyのSQLクエリがschoolid、それはmaskname、ちょうどそのmaskidでは最初の3行を見てくれSQL Serverでgroup_concatを使用してクエリを作成する方法

enter image description here

のような結果を与える

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 ; 

で、schoolnameは同じですが、そうしたい異なるmaskdetailです1つに最後の列には、マスクIDごとにすべてのマスク詳細を含めることができます。

私はそのためのクエリをしながら

enter image description here

だから、私のような出力がon.So私を助けてくださいしたいです。

ありがとうございます。

+1

[STRING_AGG](https://docs.microsoft.com/en-us/sql/t-sql/functions)が追加されて以来、これはSQL Server 2005に関する質問と重複していません。/string-agg-transact-sql)をSQL Server 2017に移行するため、最新のSQL Serverに恵まれているかどうかを調べることをお勧めします。 –

答えて

92

問合せ:

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 

追加情報:

String Aggregation in the World of SQL Server

+0

hmmmあなたは@Devartを説明することができますか?画像のような結果を与える内側の結合を意味する...すべての重複するm.maskidを組み合わせる 、m.maskname 、m.schoolid 、s.schoolnameは必要な行 –

+5

'tblmask' - ' maskdetails' = '1 to many'の関係ですので、レコードの重複はここにはありません。 – Devart

+0

@ AmitSinghのasnwerのような単純な 'PATH( '')'とは対照的に、 'PATH( '')、TYPE'、' .value( '。'、 'NVARCHAR(MAX)') ?あなたの変種は、より重い実行計画の道をもたらします。コストを正当化する隠れた優位性を持っていますか?そうでない場合は、それが受け入れられ、最高のものと思われるので、あなたの答えを修正したり修正したりしますか? – 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。ところで、ここではGROUP BYは必要ありません。 – Devart

5

以下のクエリを実行してください、それはあなたのケースでSTUFFとGROUP BYを必要としません。 :

Select 
     A.maskid 
    , A.maskname 
    , A.schoolid 
    , B.schoolname 
    , CAST((
      SELECT T.maskdetail+',' 
      FROM dbo.maskdetails T 
      WHERE A.maskid = T.maskid 
      FOR XML PATH(''))as varchar(max)) as maskdetail 
FROM dbo.tblmask A 
JOIN dbo.school B ON B.ID = A.schoolid 
+3

STUFFは、最初のコンマを取り除くために必要です。あなたのケースでは、maskdetailはカンマで終わります。 –

6

これはまた、次のようにあなたの関数を宣言し

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 

してから、最終的な問合せは

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 ; 

ノートのようになりますMSSQL 2008
Scalar-Valued Functionを使用して達成することができます。
ます私は完全なテーブル構造を知らないので、関数を変更する必要があります。

+0

もご覧ください:https://gooroo.io/GoorooTHINK/Article/10001/Aggregate-String-Concatenation-in-SQL-Server-2012- like-stringagg-in-PostgreSQL/5122#.Wif5rLaZMWo – Magne

関連する問題