SQL සේවාදායකයේ පේළි කිහිපයක සිට තනි පෙළ පෙළකට සංයුක්ත කරන්නේ කෙසේද?


1924

පේළි තුනක් සහිත නම් සහිත දත්ත සමුදා වගුවක් සලකා බලන්න:

Peter
Paul
Mary

මෙය තනි නූලක් බවට පත් කිරීමට පහසු ක්‍රමයක් Peter, Paul, Maryතිබේද?


26
SQL සේවාදායකයට විශේෂිත පිළිතුරු සඳහා, මෙම ප්‍රශ්නය උත්සාහ කරන්න .
මැට් හැමිල්ටන්

17
MySQL සඳහා, පරීක්ෂා Group_Concat සිට මෙම පිළිතුර
Pykler

26
XML PATH හි මෝඩකමකින් තොරව SQL සේවාදායකයේ මීළඟ අනුවාදය බහු-පේළි සමෝච්ඡය අලංකාර ලෙස විසඳීමට නව අංගයක් ලබා දෙනු ඇතැයි මම ප්‍රාර්ථනා කරමි.
පීට් ඇල්වින්

4
SQL නොවේ, නමුත් මෙය එක් වරක් පමණක් වූ දෙයක් නම්, ඔබට මෙම බ්‍රව්සර් මෙවලම තුළට ලැයිස්තුව ඇලවිය හැකිය convert.town/column-to-comma-separated-list
Stack Man

3
ඔරකල්හිදී ඔබට 11g r2 සිට LISTAGG (COLUMN_NAME) භාවිතා කළ හැකිය. ඊට පෙර WM_CONCAT (COLUMN_NAME) නමින් සහාය නොදක්වන ශ්‍රිතයක් ඇත.
රිචඩ්

Answers:


1442

ඔබ SQL Server 2017 හෝ Azure හි සිටී නම්, Mathieu Renda පිළිතුර බලන්න .

මම එක හා බොහෝ සම්බන්ධතා ඇති වගු දෙකකට සම්බන්ධ වීමට උත්සාහ කරන විට මට සමාන ප්‍රශ්නයක් ඇති විය. SQL 2005 දී මට එය හමු වියXML PATH ක්‍රමයට පේළි වල සංක්ෂිප්තය ඉතා පහසුවෙන් හැසිරවිය හැකි බවයි.

නම් මේසයක් තිබේ නම් STUDENTS

SubjectID       StudentName
----------      -------------
1               Mary
1               John
1               Sam
2               Alaina
2               Edward

මම බලාපොරොත්තු වූ ප්‍රති ult ලය වූයේ:

SubjectID       StudentName
----------      -------------
1               Mary, John, Sam
2               Alaina, Edward

මම පහත සඳහන් දෑ භාවිතා කළෙමි T-SQL:

SELECT Main.SubjectID,
       LEFT(Main.Students,Len(Main.Students)-1) As "Students"
FROM
    (
        SELECT DISTINCT ST2.SubjectID, 
            (
                SELECT ST1.StudentName + ',' AS [text()]
                FROM dbo.Students ST1
                WHERE ST1.SubjectID = ST2.SubjectID
                ORDER BY ST1.SubjectID
                FOR XML PATH ('')
            ) [Students]
        FROM dbo.Students ST2
    ) [Main]

ආරම්භයේදීම කොමාව සංයුක්ත substringකර පළමු එක මඟ හැරීමට ඔබට හැකි නම් ඔබට උප-විමසුමක් කිරීමට අවශ්‍ය නොවන්නේ නම් ඔබට එකම දේ වඩාත් සංයුක්ත ආකාරයකින් කළ හැකිය :

SELECT DISTINCT ST2.SubjectID, 
    SUBSTRING(
        (
            SELECT ','+ST1.StudentName  AS [text()]
            FROM dbo.Students ST1
            WHERE ST1.SubjectID = ST2.SubjectID
            ORDER BY ST1.SubjectID
            FOR XML PATH ('')
        ), 2, 1000) [Students]
FROM dbo.Students ST2

13
විශිෂ්ට විසඳුමක්. ඔබට HTML වැනි විශේෂ අක්ෂර හැසිරවීමට අවශ්‍ය නම් පහත සඳහන් දෑ ප්‍රයෝජනවත් විය හැකිය: රොබ් ෆාර්ලි: XML PATH ('') සමඟ විශේෂ අක්ෂර හැසිරවීම .

10
පෙනෙන විදිහට නම් වල XML අක්ෂර <හෝ වැනි නම් අඩංගු නොවේ &. @ බෙන්හින්මන්ගේ අදහස බලන්න.
සෑම්

23
සැ.යු: මෙම ක්‍රමය ලේඛනගත නොකළ හැසිරීම මත රඳා පවතී FOR XML PATH (''). ඕනෑම පැච් එකකට හෝ යාවත්කාලීනයකට මෙම ක්‍රියාකාරිත්වය වෙනස් කළ හැකි බැවින් එය විශ්වාසදායක ලෙස නොසැලකිය යුතුය. එය මූලික වශයෙන් රඳා පවතින්නේ අතහැර දැමූ අංගයක් මත ය.
බේකන් බිට්ස්

26
හෙල්කාහෝලිස්වාදය මෙහි අවසාන රේඛාව වන්නේ එක්ස්එම්එල් FOR XMLඋත්පාදනය කිරීමට මිස අත්තනෝමතික නූල් වලට සමගාමීව නොවේ. එය ගැළවෙන ඇයි කියලා &, <සහ >XML ආයතනයක් කේත ( &amp;, &lt;, &gt;). මම එය ද සිටිනු ඇත උපකල්පනය "හා 'කිරීමට &quot;හා &apos;මෙන්ම ගුණාංගයන්ගෙන්. ඒක නැති GROUP_CONCAT() , string_agg(), array_agg(), listagg()ඔබ වගේ බැකප් එය කළ හැකි වුවද, ආදිය. අප කළ යුතු මයික්රොසොෆ්ට් නිසි කාර්යය ක්රියාත්මක ඉල්ලා අපගේ කාලය ගත කළ යුතුය.
බේකන් බිට්ස්

13
ශුභාරංචිය: MS SQL සේවාදායකය string_aggv.Next හි එකතු කරනු ඇත . මේ සියල්ල පහව යා හැකිය.
ජේසන් සී

1015

මෙම පිළිතුර අනපේක්ෂිත ප්‍රති results ල ලබා දිය හැකිය ස්ථාවර ප්‍රති results ල සඳහා, වෙනත් පිළිතුරු වල විස්තර කර ඇති FOR XML PATH ක්‍රමවලින් එකක් භාවිතා කරන්න.

භාවිතා කරන්න COALESCE:

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(@Names + ', ', '') + Name 
FROM People

යම් පැහැදිලි කිරීමක් පමණි (මෙම පිළිතුර සාපේක්ෂව නිත්‍ය අදහස් ලබා ගන්නා බව පෙනේ):

  • Coalesce යනු කාරණා දෙකක් ඉටු කරන ප්‍රයෝජනවත් වංචාවකි:

1) @Namesහිස් නූල් අගයකින් ආරම්භ කිරීම අවශ්‍ය නොවේ .

2) අවසානයේ අතිරේක බෙදුම්කරුවෙකු ඉවත් කිරීමට අවශ්‍ය නැත.

  • පේලියට සතුව නම් ඉහත විසඳුම වැරදි ප්රතිඵල ලබා දෙනු ඇත NULL (නම වටිනාකම තිබේ නම් NULL එම NULL කරන්නෙමි @Names NULL ලෑම බව පසු, ඊළඟ පේළිය නැවත හිස් අගයක් ලෙස නැවත ආරම්භ වනු ඇත. පහසුවෙන් පාලනය කරන්න දෙකෙන් එකක්, ස්ථාවර විසඳුම්:
DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(@Names + ', ', '') + Name
FROM People
WHERE Name IS NOT NULL

හෝ:

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(@Names + ', ', '') + 
    ISNULL(Name, 'N/A')
FROM People

ඔබට අවශ්‍ය හැසිරීම මත පදනම්ව (පළමු විකල්පය NULL පිටතට පෙරීම , දෙවන විකල්පය ඒවා සලකුණු පණිවිඩයක් සමඟ ලැයිස්තුවේ තබා ගනී ['N / A' වෙනුවට ඔබට සුදුසු ඕනෑම දෙයක් ආදේශ කරන්න]).


72
පැහැදිලිව කිවහොත්, ලැයිස්තුව නිර්මාණය කිරීම සමඟ coalesce ට කිසිදු සම්බන්ධයක් නැත, එය NULL අගයන් ඇතුළත් නොකිරීමට වග බලා ගනී.
ග්‍රේම් පෙරෝ

17
Ra ග්‍රේම් පෙරෝ එය NULL අගයන් බැහැර නොකරයි (ඒ සඳහා WHERE එකක් අවශ්‍ය වේ - ආදාන අගයන්ගෙන් එකක් NULL නම් මෙය ප්‍රති results ල අහිමි වනු ඇත ), මෙම ප්‍රවේශයේදී එය අවශ්‍ය වන්නේ: NULL + NULL නොවන -> NULL සහ NULL + NULL -> NULL; ame නම පෙරනිමියෙන් NULL වන අතර ඇත්ත වශයෙන්ම එම දේපල ',' එකතු කළ යුතුද නැද්ද යන්න තීරණය කිරීම සඳහා මෙහි ව්‍යාජ සෙන්ඩිනල්වරයකු ලෙස භාවිතා කරයි.

62
මෙම සංයුක්ත කිරීමේ ක්‍රමය රඳා පවතින්නේ විශේෂිත සැලැස්මක් සමඟ විමසුම ක්‍රියාත්මක කරන SQL සේවාදායකය මත ය. මෙම ක්‍රමය භාවිතා කරමින් මා හසු වී ඇත (නියෝගයක් එකතු කිරීමත් සමඟ). එය පේළි කුඩා සංඛ්‍යාවක් සමඟ ගනුදෙනු කරන විට එය හොඳින් ක්‍රියාත්මක වූ නමුත් වැඩි දත්ත ප්‍රමාණයක් සහිත SQL සේවාදායකය වෙනස් සැලැස්මක් තෝරා ගත් අතර එහි ප්‍රති ulted ලය වූයේ පළමු අයිතමය තෝරාගැනීමේදී කිසිදු සංක්ෂිප්තයක් නොමැති වීමයි. මෙම ලිපිය බලන්න අනිත් සෙන්
fbarber

17
මෙම ක්‍රමය tSQL විචල්‍යයක් භාවිතා කරන බැවින් තෝරාගත් ලැයිස්තුවක හෝ කොතැනක හෝ උප විමසුමක් ලෙස භාවිතා කළ නොහැක. එවැනි අවස්ථාවන්හිදී ඔබට @ රිටේෂ්
ආර්.

11
මෙය විශ්වාසදායක සංයුක්ත ක්‍රමයක් නොවේ. එය සහාය නොදක්වන සහ (මයික්රොසොෆ්ට්, උදා: එක් භාවිතා කල යුතු නොවේ support.microsoft.com/en-us/kb/287515 , connect.microsoft.com/SQLServer/Feedback/Details/704389 ). අනතුරු ඇඟවීමකින් තොරව එය වෙනස් විය හැකිය. මෙම XML PATH තාක්ෂණය සාකච්ඡා භාවිතා stackoverflow.com/questions/5031204/... : මට තව මෙතන ලියා marc.durdin.net/2015/07/...
මාක් Durdin

462

SQL සේවාදායකය 2017+ සහ SQL Azure: STRING_AGG

SQL සේවාදායකයේ මීළඟ අනුවාදයෙන් පටන් ගෙන, අපට කිසිදු විචල්‍යයක් හෝ එක්ස්එම්එල් මායාකාරියකට යොමු නොවී පේළි හරහා සමපාත විය හැකිය.

STRING_AGG (ගනුදෙනු- SQL)

කණ්ඩායම් කිරීමකින් තොරව

SELECT STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department;

කණ්ඩායම් කිරීම සමඟ:

SELECT GroupName, STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department
GROUP BY GroupName;

කණ්ඩායම්කරණය සහ උප වර්ග කිරීම සමඟ

SELECT GroupName, STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name ASC) AS Departments
FROM HumanResources.Department 
GROUP BY GroupName;

2
තවද, සීඑල්ආර් විසඳුම් මෙන් නොව, වර්ග කිරීම පාලනය කිරීමට ඔබට හැකිය.
කැනන්

STRING_AGG හි අක්ෂර 4000 ක දර්ශන සීමාවක් ඇති බව පෙනේ
InspiredBy

GROUP BY නොමැති නම් වර්ග කිරීම සඳහා ක්‍රමයක් තිබේද (එසේ නම් “කණ්ඩායම් කිරීමකින් තොරව” උදාහරණය සඳහා)?
RuudvK

යාවත්කාලීන කිරීම: පහත සඳහන් දෑ කිරීමට මට හැකි විය, නමුත් වඩා පිරිසිදු ක්‍රමයක් තිබේද? STRING_AGG තෝරන්න (නම, ',') දෙපාර්තමේන්තු වලින් (මානව සම්පත් වලින් ඉහළම 100000 නම තෝරන්න. නම අනුව දෙපාර්තමේන්තු නියෝගය) D;
RuudvK

365

XML data()MS SQL සේවාදායකයේ විධානය හරහා තවමත් පෙන්වා නැති එක් ක්‍රමයක් නම්:

FName නම් එක් තීරුවක් සමඟ NameList නම් වගුව උපකල්පනය කරන්න,

SELECT FName + ', ' AS 'data()' 
FROM NameList 
FOR XML PATH('')

ප්‍රතිලාභ:

"Peter, Paul, Mary, "

අතිරේක කොමාව සමඟ පමණක් කටයුතු කළ යුතුය.

සංස්කරණය කරන්න: @ එන්. රයිලිංගේ අදහස් දැක්වීමෙන්, ඔබට පහත සඳහන් ක්‍රමය භාවිතා කර පසුපස කොමාව ඉවත් කළ හැකිය. එකම වගුව සහ තීරු නම් උපකල්පනය කිරීම:

STUFF(REPLACE((SELECT '#!' + LTRIM(RTRIM(FName)) AS 'data()' FROM NameList
FOR XML PATH('')),' #!',', '), 1, 2, '') as Brands

15
ශුද්ධ s ** t පුදුම සහගතයි! ඔබේ උදාහරණයේ දී මෙන් ප්‍රති result ලය හයිපර්ලින්ක් ලෙස සංයුති කර ඇති විට, ක්ලික් කළ විට (එස්එස්එම්එස් හි) දත්ත අඩංගු නව කවුළුවක් විවෘත වේ, නමුත් විශාල විමසුමක කොටසක් ලෙස භාවිතා කරන විට එය නූලක් ලෙස දිස් වේ. එය නූලක් ද? නැතහොත් මෙම දත්ත භාවිතා කරන යෙදුමේදී මට වෙනස් ආකාරයකින් සැලකීමට අවශ්‍ය වන්නේ xml ද?
බෙන්

10
මෙම ප්‍රවේශය <සහ> වැනි XML වලින් ගැලවී යයි. එබැවින්, '<b>' + FName + '</b>' තේරීමෙන් "& lt; b & gt; John & lt; / b & gt; & lt; b & gt; Paul ..."
Lukáš Lánský

8
පිළිවෙලට විසඳුම. මම එකතු නොකරන විට පවා + ', 'එය සෑම සංයුක්ත මූලද්‍රව්‍යයක් අතර තනි ඉඩක් එක් කරන බව මම දනිමි .
බයෝඩාඩ්

8
A බයෝඩාඩ් එය ගනුදෙනුවේ කොටසක් ලෙස පෙනේ. එකතු කළ ටෝකන අක්‍ෂරයක් ආදේශ කිරීමෙන් ඔබට ක්‍රියා කළ හැකිය. උදාහරණයක් ලෙස, මෙය ඕනෑම දිගක් සඳහා කොමා වලින් වෙන් කරන ලද පරිපූර්ණ ලැයිස්තුවක් කරයි:SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
එන් රයිලිං

1
ඇවැත්නි, ඇත්ත වශයෙන්ම දත්ත () භාවිතා කරමින් මගේ පරීක්ෂණයේදී ප්‍රතිස්ථාපනය WAY වඩා ක්‍රියාකාරී වේ. සුපිරි අමුතුයි.
එන් රයිලිං

307

දී 2005 SQL Server

SELECT Stuff(
  (SELECT N', ' + Name FROM Names FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'')

SQL සේවාදායකය 2016 දී

ඔබට FOR JSON සින්ටැක්ස් භාවිතා කළ හැකිය

එනම්

SELECT per.ID,
Emails = JSON_VALUE(
   REPLACE(
     (SELECT _ = em.Email FROM Email em WHERE em.Person = per.ID FOR JSON PATH)
    ,'"},{"_":"',', '),'$[0]._'
) 
FROM Person per

ප්රති result ලය බවට පත්වනු ඇත

Id  Emails
1   abc@gmail.com
2   NULL
3   def@gmail.com, xyz@gmail.com

ඔබගේ දත්ත වල පවා වලංගු නොවන XML අක්ෂර අඩංගු වේ

මෙම '"},{"_":"'නිසා ඔබ විසින් දත්ත අඩංගු නම් ආරක්ෂිත '"},{"_":"',එය පලා කරනු ඇත"},{\"_\":\"

ඔබට ', 'ඕනෑම නූල් බෙදුම්කරුවෙකු සමඟ ප්රතිස්ථාපනය කළ හැකිය


සහ SQL Server 2017 හි Azure SQL දත්ත සමුදාය

ඔබට නව STRING_AGG ශ්‍රිතය භාවිතා කළ හැකිය


3
ප්‍රමුඛ අක්ෂර දෙක නික්ස් කිරීම සඳහා STUFF ශ්‍රිතය හොඳින් භාවිතා කිරීම.
ඩේවිඩ්

3
මම මෙම විසඳුමට වඩාත්ම කැමතියි, මන්දයත් '<label>' ලෙස එකතු කිරීමෙන් තෝරාගත් ලැයිස්තුවක එය පහසුවෙන් භාවිතා කළ හැකිය. Ites රිතේෂ්ගේ විසඳුම සමඟ මෙය කරන්නේ කෙසේදැයි මට විශ්වාස නැත.
ආර්. ෂ්චර්ස්

13
මෙම විකල්පය ද වැනි එක්සත් ජාතීන්ගේ-පලා එන XML ඇවිරිණි චරිත හසුරුවන නිසා මෙය පිළිගත් පිළිතුර වඩා යහපත් වන්නේ <, >, &, ආදී වූ FOR XML PATH('')ස්වයංක්රීයව පැන ඇත.
BateTech

මෙය අපූරු ප්‍රතිචාරයක් වන අතර එය ගැටළුව විසඳා ඇති අතර SQL හි විවිධ සංස්කරණවල හොඳම දේ කිරීමට දැන් මම ප්‍රාර්ථනා කරමි 2017 / Azure
Chris Ward

122

MySQL හි GROUP_CONCAT () ශ්‍රිතයක් ඇත, එමඟින් ඔබට පේළි කිහිපයකින් අගයන් සංයුක්ත කිරීමට ඉඩ ලබා දේ. උදාහරණයක්:

SELECT 1 AS a, GROUP_CONCAT(name ORDER BY name ASC SEPARATOR ', ') AS people 
FROM users 
WHERE id IN (1,2,3) 
GROUP BY a

හොඳින් ක්රියා කරයි. නමුත් මම භාවිතා SEPARATOR '", "'කරන විට අවසාන පිවිසුම අවසානයේ මට අක්ෂර කිහිපයක් මග හැරෙනු ඇත. මෙය සිදුවිය හැක්කේ ඇයි?
gooleem

olegooleem ඔබ අදහස් කරන්නේ කුමක්ද යන්න පිළිබඳව මට පැහැදිලි නැත, නමුත් මෙම ශ්‍රිතය මඟින් අයිතම අතර බෙදුම්කරු තබන්නේ පසුව නොවේ. එය පිළිතුර නොවේ නම්, මම නව ප්‍රශ්නයක් පළ කිරීමට නිර්දේශ කරමි.
ඩැරල් හයින්

Ard ඩැරල්හයින් මගේ අවශ්‍යතා සඳහා මම ඉහත පරිදි බෙදුම්කරු භාවිතා කළෙමි. නමුත් මෙය නිමැවුමේ අවසානයේ සමහර අක්ෂර කපා දමයි. මෙය ඉතා අමුතු දෙයක් වන අතර එය දෝෂයක් ලෙස පෙනේ. මට විසඳුමක් නැහැ, මම වැඩ කළා.
gooleem

මූලික වශයෙන් ක්රියා කරයි. සලකා බැලිය යුතු කරුණු දෙකක්: 1) ඔබේ තීරුව a නොවේ නම් CHAR, ඔබ එය දැමිය යුතුය, උදා. GROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')2 හරහා ) ඔබට බොහෝ අගයන් පැමිණේ නම්, ඔබ stackoverflow.com/a/1278210/1498405group_concat_max_len හි ලියා ඇති පරිදි වැඩි කළ යුතුය
hardmooth

61

COALESCE භාවිතා කරන්න - මෙතැන් සිට වැඩිදුර ඉගෙන ගන්න

උදාහරණයක් ලෙස:

102

103 යි

104 යි

ඉන්පසු SQL සේවාදායකයේ පහත කේතය ලියන්න,

Declare @Numbers AS Nvarchar(MAX) -- It must not be MAX if you have few numbers 
SELECT  @Numbers = COALESCE(@Numbers + ',', '') + Number
FROM   TableName where Number IS NOT NULL

SELECT @Numbers

ප්‍රතිදානය වනුයේ:

102,103,104

2
XML සඳහා ඉදිරිපත් කරන කේතීකරණ ගැටළු මඟහරින බැවින් මෙය සැබවින්ම හොඳම විසඳුම IMO වේ. මම භාවිතා කළ Declare @Numbers AS Nvarchar(MAX)අතර එය හොඳින් ක්‍රියාත්මක විය. කරුණාකර එය භාවිතා නොකිරීමට ඔබ නිර්දේශ කරන්නේ මන්දැයි ඔබට පැහැදිලි කළ හැකිද?
EvilDr

7
මෙම විසඳුම මීට වසර 8 කට පෙර දැනටමත් පළ කර ඇත! stackoverflow.com/a/194887/986862
ඇන්ඩ්‍රේ

මෙම විමසුම නැවත පැමිණෙන්නේ ඇයි ??? සිරිලික් වෙනුවට සංකේත? මෙය ප්‍රතිදාන නිකුතුවක්ද?
අක්මාල් සාලිකොව්

48

Postgres අරා නියමයි. උදාහරණයක්:

පරීක්ෂණ දත්ත කිහිපයක් සාදන්න:

postgres=# \c test
You are now connected to database "test" as user "hgimenez".
test=# create table names (name text);
CREATE TABLE                                      
test=# insert into names (name) values ('Peter'), ('Paul'), ('Mary');                                                          
INSERT 0 3
test=# select * from names;
 name  
-------
 Peter
 Paul
 Mary
(3 rows)

ඒවා පෙළට එකතු කරන්න:

test=# select array_agg(name) from names;
 array_agg     
------------------- 
 {Peter,Paul,Mary}
(1 row)

අරාව කොමා වලින් වෙන් කරන ලද නූලකට පරිවර්තනය කරන්න:

test=# select array_to_string(array_agg(name), ', ') from names;
 array_to_string
-------------------
 Peter, Paul, Mary
(1 row)

කළා

PostgreSQL 9.0 සිට එය ඊටත් වඩා පහසුය .


ඔබට එක් තීරුවකට වඩා අවශ්‍ය නම්, උදාහරණයක් ලෙස වරහන් වල ඇති ඔවුන්ගේ සේවක හැඳුනුම්පත කොන්කට් ක්‍රියාකරු භාවිතා කරයි: select array_to_string(array_agg(name||'('||id||')'
රිචඩ් ෆොක්ස්

SQL

46

Oracle 11g Release 2 LISTAGG ශ්‍රිතයට සහය දක්වයි. මෙහි ලේඛනගත කිරීම .

COLUMN employees FORMAT A50

SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM   emp
GROUP BY deptno;

    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

3 rows selected.

අවවාදයයි

එහි ප්‍රති string ලයක් ලෙස අක්ෂර 4000 ඉක්මවා යාමට ඉඩ තිබේ නම් මෙම ක්‍රියාව ක්‍රියාත්මක කිරීමට ප්‍රවේශම් වන්න. එය ව්යතිරේකයක් විසි කරනු ඇත. එය එසේ නම්, ඔබට ව්‍යතිරේකය හැසිරවිය යුතුය, නැතහොත් ඔබේම ශ්‍රිතය රෝල් කළ යුතුය, එමඟින් එක්වූ නූල අක්ෂර 4000 ඉක්මවා යාම වළක්වයි.


1
ඔරකල් හි පැරණි අනුවාද සඳහා, wm_concat පරිපූර්ණයි. එහි භාවිතය ඇලෙක්ස් විසින් සබැඳි තෑග්ගෙන් විස්තර කර ඇත. ඇලෙක්ස්!
toscanelli

LISTAGGපරිපූර්ණයි! මෙහි සම්බන්ධිත ලේඛනය කියවන්න. wm_concat12c අනුවාදයෙන් ඉවත් කර ඇත.
asgs

34

SQL Server 2005 සහ ඊට පසු, පේළි සංයුක්ත කිරීම සඳහා පහත විමසුම භාවිතා කරන්න.

DECLARE @t table
(
    Id int,
    Name varchar(10)
)
INSERT INTO @t
SELECT 1,'a' UNION ALL
SELECT 1,'b' UNION ALL
SELECT 2,'c' UNION ALL
SELECT 2,'d' 

SELECT ID,
stuff(
(
    SELECT ','+ [Name] FROM @t WHERE Id = t.Id FOR XML PATH('')
),1,1,'') 
FROM (SELECT DISTINCT ID FROM @t ) t

2
අගයන් තුළ XML සංකේත <හෝ වැනි විට එය අසාර්ථක වන බව මම විශ්වාස කරමි &.
සෑම්

29

මට නිවසේදී SQL සේවාදායකයකට ප්‍රවේශය නොමැත, එබැවින් මම මෙහි වාක්‍ය ඛණ්ඩය අනුමාන කරමි, නමුත් එය වැඩි හෝ අඩු:

DECLARE @names VARCHAR(500)

SELECT @names = @names + ' ' + Name
FROM Names

11
ඔබට ශුන්‍ය නොවන දෙයකට @ නම් ආරම්භ කිරීමට අවශ්‍ය වනු ඇත, එසේ නොමැතිනම් ඔබට පුරාම NULL ලැබෙනු ඇත; ඔබට පරිමිතිය හැසිරවීමටද අවශ්‍ය වේ (අනවශ්‍ය එකක් ඇතුළුව)
මාක් ග්‍රෙවෙල්

3
මෙම ප්‍රවේශයේ ඇති එකම ගැටළුව (මම නිතරම භාවිතා කරන) ඔබට එය කාවැද්දිය නොහැකි
වීමයි

1
ප්‍රමුඛ අවකාශයෙන් මිදීම සඳහා විමසුම වෙනස් කරන්නSELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
ටියන් වැන් හීර්ඩන්

එසේම, නම ශුන්‍ය SELECT @names = @names + ISNULL(' ' + Name, '')
නොවේදැයි

28

පුනරාවර්තන CTE විසඳුමක් යෝජනා කළ නමුත් කේතයක් ලබා දී නැත. පහත කේතය පුනරාවර්තන CTE සඳහා උදාහරණයකි. ප්රතිඵල ප්රශ්නය ගැලපෙන වුවත්, දත්ත නොවන බව සටහන ඉතා ලබා දී විස්තර, මම ඔයාට ඇත්තටම මේසය නැති, පේළි කණ්ඩායම් සියලු පේළි මත මේ දේ කිරීමට අවශ්ය බව උපකල්පනය ලෙස නොගැලපේ. වගුවේ ඇති සියලුම පේළි වලට ගැලපෙන පරිදි එය වෙනස් කිරීම පා er කයාට අභ්‍යාසයක් ලෙස ඉතිරි වේ.

;WITH basetable AS (
    SELECT
        id,
        CAST(name AS VARCHAR(MAX)) name, 
        ROW_NUMBER() OVER (Partition BY id ORDER BY seq) rw, 
        COUNT(*) OVER (Partition BY id) recs 
    FROM (VALUES
        (1, 'Johnny', 1),
        (1, 'M', 2), 
        (2, 'Bill', 1),
        (2, 'S.', 4),
        (2, 'Preston', 5),
        (2, 'Esq.', 6),
        (3, 'Ted', 1),
        (3, 'Theodore', 2),
        (3, 'Logan', 3),
        (4, 'Peter', 1),
        (4, 'Paul', 2),
        (4, 'Mary', 3)
    ) g (id, name, seq)
),
rCTE AS (
    SELECT recs, id, name, rw
    FROM basetable
    WHERE rw = 1

    UNION ALL

    SELECT b.recs, r.ID, r.name +', '+ b.name name, r.rw + 1
    FROM basetable b
    INNER JOIN rCTE r ON b.id = r.id AND b.rw = r.rw + 1
)
SELECT name
FROM rCTE
WHERE recs = rw AND ID=4

1
මෙම flabbergasted සඳහා: තාවකාලික basetable බවට විමසුම් රැසක් 12 පේළි (3 තීරු), පසුව ආවර්තනික පොදු වගුව සඳහා කැමැත්ත ප්රකාශ (rCTE) නිර්මාණය කරන අතර පසුව flattens name 4 කොමා-වෙන් string එකකට තීරුව කණ්ඩායම් වල ids. බැලූ බැල්මට, මෙය SQL සේවාදායකය සඳහා වන වෙනත් බොහෝ විසඳුම් වලට වඩා වැඩක් යැයි මම සිතමි.
knb

2
nknb: එය ප්‍රශංසාව, හෙළා දැකීම හෝ පුදුමයක් දැයි විශ්වාස නැත. මූලික වගුව වන්නේ මගේ උදාහරණ සැබවින්ම වැඩ කිරීමට මා කැමති නිසා, එයට ඇත්ත වශයෙන්ම ප්‍රශ්නයට කිසිදු සම්බන්ධයක් නැත.
jmoreno

26

PostgreSQL 9.0 සමඟ ආරම්භ කිරීම මෙය බෙහෙවින් සරල ය:

select string_agg(name, ',') 
from names;

9.0 ට පෙර සංස්කරණ array_agg()වලදී hgmnz පෙන්වා ඇති පරිදි භාවිතා කළ හැකිය


යතුරු SELECT string_agg(non_text_type::text, ',') FROM table
ලියනයකින් තොර

Or ටෝර්බෙන් කොල්මියර්: ඔබට එය අවශ්‍ය වන්නේ අක්ෂර නොවන තීරු සඳහා පමණි (උදා: නිඛිල, දශම). එය හොඳින් ක්‍රියාත්මක වේ varcharහෝchar
a_horse_with_no_name

26

ඔබේ අවසාන ප්‍රති result ලය රඳවා තබා ගත හැකි විචල්‍යයක් ඔබ විසින් නිර්මාණය කළ යුතුය.

පහසුම විසඳුම

DECLARE @char VARCHAR(MAX);

SELECT @char = COALESCE(@char + ', ' + [column], [column]) 
FROM [table];

PRINT @char;


18

කොමා සමඟ පේළි වෙන් කිරීමට XML භාවිතා කිරීම මට උපකාරී විය. අමතර කොමාව සඳහා අපට SQL සේවාදායකයේ ප්‍රතිස්ථාපන කාර්යය භාවිතා කළ හැකිය. කොමාව එකතු කිරීම වෙනුවට, AS 'දත්ත ()' භාවිතා කිරීමෙන් පේළි අවකාශයන් සමඟ සංයුක්ත වන අතර පසුව එය කොමා මඟින් ප්‍රතිස්ථාපනය කළ හැකිය.

REPLACE(
        (select FName AS 'data()'  from NameList  for xml path(''))
         , ' ', ', ') 

2
මගේ මතය අනුව මෙහි ඇති හොඳම පිළිතුර මෙයයි. ඔබට වෙනත් වගුවකට සම්බන්ධ වීමට අවශ්‍ය වූ විට ප්‍රකාශන විචල්‍යය භාවිතා කිරීම හොඳ නැත, මෙය කදිම හා කෙටි ය. හොඳ වැඩක්.
ඩේවිඩ් රූසල්

7
FName දත්ත වලට දැනටමත් අවකාශ තිබේ නම් එය හොඳ නැත, උදාහරණයක් ලෙස "මගේ නම"
බින්බෝල්

ඇත්ත වශයෙන්ම එය මා වෙනුවෙන් වැඩ කරන්නේ ms-sql 2016 xml path ('') සඳහා '', '', '', ' , ') allBrands ලෙස
Rejwanul Reja

17

අමතර කොමාවකින් තොරව භාවිතා කිරීමට සූදානම් විසඳුමක්:

select substring(
        (select ', '+Name AS 'data()' from Names for xml path(''))
       ,3, 255) as "MyList"

හිස් ලැයිස්තුවක් නිසා NULL අගය ලැබෙනු ඇත. සාමාන්‍යයෙන් ඔබ ලැයිස්තුව වගු තීරුවකට හෝ ක්‍රමලේඛ විචල්‍යයකට ඇතුළත් කරනු ඇත: ඔබේ අවශ්‍යතාවයට අනුව උපරිම දිග 255 ක් සකසන්න.

(දීවාකර් සහ ජෙන්ස් ෆ්‍රැන්ඩ්සන් හොඳ පිළිතුරු සැපයූ නමුත් වැඩිදියුණු කිරීම අවශ්‍යයි.)


මෙය භාවිතා කරන විට
කොමාවට

1
යන්තම් වෙනුවට ', 'සමග ','ඔබ වැඩිපුර ඉඩ අවශ්ය නැති නම්.
ඩැනියෙල් රීස්

13
SELECT STUFF((SELECT ', ' + name FROM [table] FOR XML PATH('')), 1, 2, '')

මෙන්න නියැදියක්:

DECLARE @t TABLE (name VARCHAR(10))
INSERT INTO @t VALUES ('Peter'), ('Paul'), ('Mary')
SELECT STUFF((SELECT ', ' + name FROM @t FOR XML PATH('')), 1, 2, '')
--Peter, Paul, Mary

10
DECLARE @Names VARCHAR(8000)
SELECT @name = ''
SELECT @Names = @Names + ',' + Names FROM People
SELECT SUBSTRING(2, @Names, 7998)

මෙය අයාලේ යන කොමාව ආරම්භයේදීම තබයි.

කෙසේ වෙතත්, ඔබට වෙනත් තීරු අවශ්‍ය නම්, හෝ ළමා වගුවකට CSV කිරීමට අවශ්‍ය නම්, මෙය පරිමාණ පරිශීලක අර්ථ දක්වා ඇති ක්ෂේත්‍රයක (යූඩීඑෆ්) ඔතා තැබිය යුතුය.

SELECT වගන්තියේ සහසම්බන්ධිත අනුකාරකයක් ලෙස ඔබට XML මාර්ගය භාවිතා කළ හැකිය (නමුත් ගූගල් නිවසේදී වැඩ කටයුතු නොකරන නිසා මම නැවත වැඩට යන තෙක් බලා සිටිය යුතුය :-)


10

අනෙක් පිළිතුරු සමඟ, පිළිතුර කියවන පුද්ගලයා වාහනය හෝ ශිෂ්‍යයා වැනි නිශ්චිත වසම් වගුවක් පිළිබඳව දැනුවත් විය යුතුය. විසඳුමක් පරීක්ෂා කිරීම සඳහා වගුව නිර්මාණය කර දත්ත වලින් පිරී තිබිය යුතුය.

පහත දැක්වෙන්නේ SQL සේවාදායකයේ "Information_Schema.Columns" වගුව භාවිතා කරන උදාහරණයකි. මෙම විසඳුම භාවිතා කිරීමෙන් වගු සෑදීම හෝ දත්ත එකතු කිරීම අවශ්‍ය නොවේ. මෙම උදාහරණය මඟින් දත්ත සමුදායේ ඇති සියලුම වගු සඳහා කොමා මඟින් වෙන් කරන ලද තීරු නම් ලැයිස්තුවක් නිර්මාණය කරයි.

SELECT
    Table_Name
    ,STUFF((
        SELECT ',' + Column_Name
        FROM INFORMATION_SCHEMA.Columns Columns
        WHERE Tables.Table_Name = Columns.Table_Name
        ORDER BY Column_Name
        FOR XML PATH ('')), 1, 1, ''
    )Columns
FROM INFORMATION_SCHEMA.Columns Tables
GROUP BY TABLE_NAME 

7

ඔරකල් ඩීබී සඳහා, මෙම ප්‍රශ්නය බලන්න: ගබඩා කළ ක්‍රියා පටිපාටියක් නිර්මාණය නොකර පේළි කිහිපයක් ඔරකල් එකකට එකකට සම්බන්ධ කරන්නේ කෙසේද?

හොඳම පිළිතුර ලෙස පෙනෙන්නේ එමානුවෙල්, බිල්ට් ලිස්ටැග් () ශ්‍රිතය භාවිතා කරමින්, ඔරකල් 11g නිකුතුව 2 සහ පසුව ලබා ගත හැකි බවයි.

SELECT question_id,
   LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE;
GROUP BY question_id

@ user762952 පෙන්වා ඇති පරිදි, සහ ඔරකල්ගේ ලියකියවිලි අනුව http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , WM_CONCAT () ශ්‍රිතය ද විකල්පයකි. එය ස්ථායී බවක් පෙනේ, නමුත් ඕනෑම යෙදුමක SQL සඳහා එය භාවිතා කිරීමට එරෙහිව ඔරකල් පැහැදිලිවම නිර්දේශ කරයි, එබැවින් ඔබේම අවදානමක භාවිතා කරන්න.

ඒ හැර, ඔබට ඔබේම කාර්යයක් ලිවීමට සිදුවේ; ඉහත ඔරකල් ලේඛනයේ එය කරන්නේ කෙසේද යන්න පිළිබඳ මාර්ගෝපදේශයක් ඇත.


7

ශුන්‍ය අගයන් වළක්වා ගැනීමට ඔබට CONCAT () භාවිතා කළ හැකිය

DECLARE @names VARCHAR(500)
SELECT @names = CONCAT(@names, ' ', name) 
FROM Names
select @names

CONCAT ක්‍රියා කරන්නේ මන්දැයි දැන ගැනීම සතුටක් . MSDN වෙත සබැඳියක් හොඳයි.
ආපසු හරවන ලද ඉංජිනේරු

7

මම ඇත්තටම කැමතියි ඩනාගේ පිළිතුරේ අලංකාරයට . එය සම්පූර්ණ කිරීමට අවශ්‍ය විය.

DECLARE @names VARCHAR(MAX)
SET @names = ''

SELECT @names = @names + ', ' + Name FROM Names 

-- Deleting last two symbols (', ')
SET @sSql = LEFT(@sSql, LEN(@sSql) - 1)

ඔබ ',' යන අවසාන සංකේත දෙක මකා දමන්නේ නම්, ඔබ නමට පසුව ',' එකතු කළ යුතුය ('SELECT @ @names = @ @ නම් + නම +', 'නම් වලින්'). ඒ ආකාරයෙන් අවසාන අක්ෂර දෙක සැමවිටම ',' වනු ඇත.
JT_

මගේ නඩුවේදී මට ප්‍රමුඛ කොමාවෙන් මිදීමට අවශ්‍ය විය, එබැවින් විමසුම වෙනස් කර SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Namesපසුව ඔබ එය කපා දැමිය යුතු නැත.
ටියාන් වෑන් හියර්ඩන්

6

මෙම පිළිතුරට සේවාදායකයේ වැඩ කිරීමට යම් වරප්‍රසාදයක් අවශ්‍ය වේ.

එකලස් කිරීම ඔබට හොඳ විකල්පයකි. එය නිර්මාණය කරන්නේ කෙසේද යන්න පැහැදිලි කරන අඩවි ගොඩක් තිබේ. මම ඉතා හොඳින් විස්තර කර ඇත හිතන්නේ එක මේ එක

ඔබට අවශ්‍ය නම්, මම දැනටමත් එකලස් කිරීම නිර්මාණය කර ඇති අතර, ඩීඑල්එල් මෙතැනින් බාගත හැකිය .

ඔබ එය බාගත කළ පසු, ඔබේ SQL සේවාදායකයේ පහත ස්ක්‍රිප්ට් ධාවනය කිරීමට ඔබට අවශ්‍ය වනු ඇත:

CREATE Assembly concat_assembly 
   AUTHORIZATION dbo 
   FROM '<PATH TO Concat.dll IN SERVER>' 
   WITH PERMISSION_SET = SAFE; 
GO 

CREATE AGGREGATE dbo.concat ( 

    @Value NVARCHAR(MAX) 
  , @Delimiter NVARCHAR(4000) 

) RETURNS NVARCHAR(MAX) 
EXTERNAL Name concat_assembly.[Concat.Concat]; 
GO  

sp_configure 'clr enabled', 1;
RECONFIGURE

එකලස් කිරීමේ මාර්ගය සේවාදායකයට ප්‍රවේශ විය හැකි බව නිරීක්ෂණය කරන්න. ඔබ සියලු පියවර සාර්ථකව සිදු කර ඇති බැවින්, ඔබට පහත පරිදි ශ්‍රිතය භාවිතා කළ හැකිය:

SELECT dbo.Concat(field1, ',')
FROM Table1

එය උපකාරී වේ යැයි සිතමු !!!


1
ඩීඑල්එල් සබැඳිය 404 දෝෂයකි. මේ සඳහා එකලස් කිරීමක් භාවිතා කිරීම අධික ලෙස මරා දැමීමකි. SQL සේවාදායකය සඳහා හොඳම පිළිතුර බලන්න .
Protiguous

6

MySQL සම්පූර්ණ උදාහරණය:

අපට බොහෝ දත්ත තිබිය හැකි පරිශීලකයින් සිටින අතර අපට ප්‍රතිදානයක් ලබා ගැනීමට අවශ්‍යය, එහිදී අපට සියලු පරිශීලකයින්ගේ දත්ත ලැයිස්තුවක් තුළ දැකිය හැකිය:

ප්‍රති ult ලය:

___________________________
| id   |  rowList         |
|-------------------------|
| 0    | 6, 9             |
| 1    | 1,2,3,4,5,7,8,1  |
|_________________________|

වගු සැකසුම:

CREATE TABLE `Data` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;


INSERT INTO `Data` (`id`, `user_id`) VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1),
(6, 0),
(7, 1),
(8, 1),
(9, 0),
(10, 1);


CREATE TABLE `User` (
  `id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


INSERT INTO `User` (`id`) VALUES
(0),
(1);

විමසුම:

SELECT User.id, GROUP_CONCAT(Data.id ORDER BY Data.id) AS rowList FROM User LEFT JOIN Data ON User.id = Data.user_id GROUP BY User.id

5

මම සාමාන්‍යයෙන් SQL සේවාදායකයේ නූල් සංයුක්ත කිරීම සඳහා මෙවැනි තේරීමක් භාවිතා කරමි:

with lines as 
( 
  select 
    row_number() over(order by id) id, -- id is a line id
    line -- line of text.
  from
    source -- line source
), 
result_lines as 
( 
  select 
    id, 
    cast(line as nvarchar(max)) line 
  from 
    lines 
  where 
    id = 1 
  union all 
  select 
    l.id, 
    cast(r.line + N', ' + l.line as nvarchar(max))
  from 
    lines l 
    inner join 
    result_lines r 
    on 
      l.id = r.id + 1 
) 
select top 1 
  line
from
  result_lines
order by
  id desc

5

ඔබට ශුන්‍යයන් සමඟ ගනුදෙනු කිරීමට අවශ්‍ය නම්, ඔබට වගන්තියක් එක් කිරීමෙන් හෝ පළමු එක වටා තවත් COALESCE එකතු කිරීමෙන් එය කළ හැකිය.

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(COALESCE(@Names + ', ', '') + Name, @Names) FROM People

5

මෙය මා වෙනුවෙන් වැඩ කළේය ( SqlServer 2016 ):

SELECT CarNamesString = STUFF((
         SELECT ',' + [Name]
            FROM tbl_cars 
            FOR XML PATH('')
         ), 1, 1, '')

මූලාශ්‍රය මෙන්න: https://www.mytecbits.com/

සහ MySQL සඳහා විසඳුමක් (මෙම පිටුව ගූගල් හි MySQL සඳහා පෙන්වන බැවින්)

SELECT [Name],
       GROUP_CONCAT(DISTINCT [Name]  SEPARATOR ',')
       FROM tbl_cars

සිට MySQL ලියකියවිලි



4

මෙයද ප්‍රයෝජනවත් විය හැකිය

create table #test (id int,name varchar(10))
--use separate inserts on older versions of SQL Server
insert into #test values (1,'Peter'), (1,'Paul'), (1,'Mary'), (2,'Alex'), (3,'Jack')

DECLARE @t VARCHAR(255)
SELECT @t = ISNULL(@t + ',' + name, name) FROM #test WHERE id = 1
select @t
drop table #test

ප්‍රතිලාභ

Peter,Paul,Mary

5
අවාසනාවට මෙම හැසිරීමට නිල වශයෙන් සහාය නොදක්වයි. එම්එස්ඩීඑන් මෙසේ කියයි: "විචල්යයක් තෝරාගත් ලැයිස්තුවක සඳහන් කර ඇත්නම්, එයට පරිමාණ අගයක් පැවරිය යුතුය, නැතහොත් SELECT ප්රකාශය නැවත ලබා දිය යුත්තේ එක් පේළියක් පමණි." ගැටළු නිරීක්ෂණය කළ අය ද සිටිති: sqlmag.com/sql-server/multi-row-variable-assignment-and-order
blueling
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.