Câu hỏi Cách tạo truy vấn với group_concat trong máy chủ sql [trùng lặp]


Câu hỏi này đã có câu trả lời ở đây:

Tôi biết rằng trong máy chủ sql, chúng tôi không thể sử dụng Group_concat nhưng đây là một vấn đề mà tôi cần Group_Concat query.I google của tôi nó tìm thấy một số logic nhưng không thể sửa nó. Truy vấn sql của tôi là

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 ;

Nó mang lại cho tôi kết quả như

enter image description here

Chỉ cần nhìn đầu tiên 3 hàng Trong maskid, maskname, schoolid, schoolname là như nhau nhưng maskdetail là khác nhau vì vậy muốn một hàng cho rằng cột cuối cùng có thể chứa tất cả maskdetails theo maskid và vân vân.

Tôi muốn sản lượng của tôi như

enter image description here

Và như vậy. Xin hãy giúp tôi trong khi thực hiện một truy vấn cho điều đó.

Cảm ơn trước.


76
2017-07-11 10:54


gốc


Đây không phải khá một bản sao của câu hỏi về SQL Server 2005 kể từ khi bổ sung STRING_AGG đến SQL Server 2017, vì vậy bạn có thể muốn xem xét điều đó nếu bạn được ban phước với một Máy chủ SQL gần đây. - Matt Gibson


Các câu trả lời:


Truy vấn:

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

Thông tin thêm:

Chuỗi tập hợp trong thế giới của SQL Server


105
2017-07-11 10:56



hmmm bạn có thể giải thích @Devart i có nghĩa là kết nối bên trong cho kết quả như trong hình ảnh ... để kết hợp trong tất cả m.maskid trùng lặp, m.maskname, m.schoolid, s.schoolname thành một hàng chúng ta cần nhóm - Amit Singh
Mối quan hệ giữa tblmask - - maskdetails = 1 to many, vì vậy bản sao của các bản ghi không nên ở đây. - Devart
Lý do để sử dụng là gì PATH(''), TYPE và .value('.', 'NVARCHAR(MAX)') ở đây, trái ngược với đơn giản PATH('') như trong asnwer @ AmitSingh? Biến thể của bạn mang lại một cách, cách kế hoạch thực hiện nặng hơn, nó có một số lợi thế ẩn để biện minh cho chi phí? Nếu không, bạn có sửa chữa hoặc sửa đổi câu trả lời của bạn vì nó được chấp nhận và được cho là tốt nhất? - pvgoran
Ok, tôi hiểu rồi. Câu trả lời của Amit Singh sẽ trả về chuỗi XML được mã hóa (vì kết quả của for xml chọn là một văn bản / đối tượng XML), ví dụ, < sẽ trở thành &gt;. Trong khi câu trả lời của bạn sẽ trả về nguyên văn chuỗi, bởi vì value() xử lý đối tượng XML và trích xuất nội dung văn bản từ đó. - pvgoran
Các tác phẩm tuyệt vời như sự quyến rũ cho nhu cầu của tôi +1 - Lee


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

20
2017-07-11 11:03



+1. Nhân tiện GROUP BY không cần thiết ở đây. - Devart


Điều này cũng có thể đạt được bằng cách sử dụng Scalar-Valued Function trong MSSQL 2008
Khai báo chức năng của bạn như sau,

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 MD.MaskId=@MaskId

    RETURN @SchoolName

END

Và sau đó truy vấn cuối cùng của bạn sẽ giống như

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 ;

Chú thích: Bạn có thể phải thay đổi hàm, vì tôi không biết cấu trúc bảng đầy đủ.


6
2017-07-18 09:55



Xem thêm: gooroo.io/GoorooTHINK/Article/10001/… - Magne


Vui lòng chạy truy vấn dưới đây, nó không yêu cầu STUFF và GROUP BY trong trường hợp của bạn:

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

5
2017-07-17 10:53



STUFF là cần thiết cho dải dấu phẩy đầu tiên, trong trường hợp của bạn maskdetail kết thúc bằng dấu phẩy - Alessandro Bernardi