কীভাবে এসকিউএল সার্ভারে একাধিক সারি থেকে পাঠ্যকে একক পাঠ্য স্ট্রিংয়ের সাথে যুক্ত করা যায়?


1910

তিনটি সারি সহ একটি ডাটাবেস টেবিলের নাম বিবেচনা করুন:

Peter
Paul
Mary

এটিকে একক স্ট্রিংয়ে রূপান্তর করার কোন সহজ উপায় আছে Peter, Paul, Mary?


26
এসকিউএল সার্ভার সম্পর্কিত নির্দিষ্ট উত্তরগুলির জন্য, এই প্রশ্নটি ব্যবহার করে দেখুন
ম্যাট হ্যামিল্টন

17
মাইএসকিউএল জন্য, খুজুন Group_Concat থেকে এই উত্তর
Pykler

26
আমি আশা করি এসকিউএল সার্ভারের পরবর্তী সংস্করণটি এক্সএমএল পথের বিন্দুতা ছাড়াই মার্জিতভাবে মাল্টি-সারি স্ট্রিং কনকিটেশনকে সমাধান করার জন্য একটি নতুন বৈশিষ্ট্য সরবরাহ করবে offer
পিট অ্যালভিন

4
না এসকিউএল, কিন্তু যদি এই একটি একসময়ের শুধুমাত্র জিনিস, আপনি এই ইন-ব্রাউজার টুল মধ্যে তালিকা আটকে দিতে পারেন convert.town/column-to-comma-separated-list
স্ট্যাক ম্যান

3
ওরাকলে আপনি 11G r2 থেকে LISTAGG (COLUMN_NAME) ব্যবহার করতে পারেন তার আগে ডাব্লুএম_কনক্যাট (COLUMN_NAME) নামে একটি অসমর্থিত ফাংশন রয়েছে যা এটি একই কাজ করে।
রিচার্ড

উত্তর:


1431

আপনি যদি এসকিউএল সার্ভার 2017 বা অ্যাজুরে থাকেন তবে ম্যাথিউ রেন্ডার উত্তর দেখুন

যখন আমি একের সাথে বহু সম্পর্কের সাথে দুটি টেবিলের সাথে যোগ দেওয়ার চেষ্টা করছিলাম তখন আমার একই রকম সমস্যা হয়েছিল। এসকিউএল 2005-এ আমি আবিষ্কার করেছি যে XML PATHপদ্ধতিটি খুব সহজেই সারিগুলির সংমিশ্রণ পরিচালনা করতে পারে।

যদি একটি টেবিল বলা হয় STUDENTS

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

আমি প্রত্যাশিত ফলাফলটি ছিল:

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 এর মতো বিশেষ চরিত্রগুলি হ্যান্ডেল করার প্রয়োজন হতে পারে: রব ফারলে: ফর এক্সএমএল পথ ('') এর সাথে বিশেষ অক্ষরগুলি পরিচালনা করা

10
দৃশ্যত এই যদি নাম যেমন এক্সএমএল অক্ষর কাজ করে না <বা &। @ বেনহিনম্যানের মন্তব্য দেখুন।
স্যাম

23
নোট: এই পদ্ধতিটি অননুমোদিত আচরণের উপর নির্ভরশীল FOR XML PATH ('')। এর অর্থ এটি কোনও নির্ভরযোগ্য হিসাবে বিবেচিত হবে না কারণ কোনও প্যাচ বা আপডেট কীভাবে এই কার্য সম্পাদন করতে পারে তা পরিবর্তন করতে পারে। এটি মূলত একটি অবহ্রাসিত বৈশিষ্ট্যের উপর নির্ভর করে।
বেকন বিটস

26
@ ওয়েলকাহোলিজম নীচের লাইনটি FOR XMLএক্সএমএল তৈরির উদ্দেশ্যে করা হয়েছে, স্বেচ্ছাসেবী স্ট্রিংগুলিকে একত্রিত করতে নয়। কেন পালাতে এর &, <এবং >এক্সএমএল সত্তা কোডগুলির ( &amp;, &lt;, &gt;)। আমি অনুমান এটি অব্যাহতি হবে "এবং 'করতে &quot;এবং &apos;গুণের হিসাবে ভাল। এটা না GROUP_CONCAT() , string_agg(), array_agg(), listagg(), ইত্যাদি আপনি করতে ধরনের এটা তা করতে পারে এমনকি যদি। আমরা উচিত মাইক্রোসফট একটি সঠিক ফাংশন বাস্তবায়ন দাবিতে আমাদের সময় কাটানোর হবে না।
বেকন বিটস

13
সুসংবাদ: এমএস এসকিউএল সার্ভার string_aggv.Next এ যুক্ত হবে । এবং এই সব দূরে যেতে পারে।
জেসন সি

1008

এই উত্তরটি অপ্রত্যাশিত ফলাফলগুলিতে ফিরে আসতে পারে ধারাবাহিক ফলাফলের জন্য, অন্যান্য উত্তরে বিশদ জন্য এক্সএমএল পথের একটি পদ্ধতি ব্যবহার করুন।

ব্যবহার COALESCE:

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

কেবলমাত্র কিছু ব্যাখ্যা (যেহেতু এই উত্তরটি তুলনামূলকভাবে নিয়মিত মতামত পেয়েছে):

  • কোলেসেস সত্যিই কেবল একটি সহায়ক প্রতারণা যা দুটি জিনিস সম্পাদন করে:

1) @Namesখালি স্ট্রিংয়ের মান দিয়ে আরম্ভ করার দরকার নেই ।

2) শেষে কোনও অতিরিক্ত বিভাজক ছিটকে যাওয়ার দরকার নেই।

  • যদি সারিটিতে একটি থাকে তবে উপরের সমাধানটি ভুল ফলাফল দেবে নুল নাম মান থাকে (যদি কোনও শূন্য থাকে , NULL সেই সারির পরে NULL করবে , এবং পরের সারিটি আবার খালি স্ট্রিং হিসাবে শুরু হবে। দুটির একটির সাথে সহজেই স্থির সমাধান:@Names
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

আপনি কী আচরণ চান তার উপর নির্ভর করে (প্রথম বিকল্পটি কেবল NUL গুলি ফিল্টার করে, দ্বিতীয় বিকল্পটি তাদেরকে একটি চিহ্নিতকারী বার্তা সহ তালিকায় রাখে [আপনার উপযুক্ত কিছুর সাথে 'এন / এ' প্রতিস্থাপন করুন])।


72
পরিষ্কার হওয়ার জন্য, তালিকা তৈরির সাথে কোলেসেসের কোনও সম্পর্ক নেই, এটি কেবল নিশ্চিত করে যে নুল মান অন্তর্ভুক্ত নয় are
গ্রীম পেরো

17
@ গ্র্যাম পেরো এটি নুল মানগুলিকে বাদ দেয় না (এর জন্য একটি প্রয়োজনীয় - এটি যদি ইনপুট মানগুলির মধ্যে একটি নুল হয় তবে এটি ফলাফল হারাবে ), এবং এটি এই পদ্ধতির প্রয়োজন কারণ: নুল + নন-নুল -> নুল এবং নন-নুল + নুল -> নুল; এছাড়াও @ নামটি ডিফল্টরূপে নুল এবং প্রকৃতপক্ষে, সম্পত্তিটি একটি ',' যুক্ত করা উচিত কিনা তা নির্ধারণ করতে এখানে একটি অন্তর্নিহিত প্রেরক হিসাবে ব্যবহৃত হয়।

62
অনুগ্রহ করে নোট করুন যে কনটেনটেশনের এই পদ্ধতিটি এসকিউএল সার্ভারের উপর নির্ভর করে একটি বিশেষ পরিকল্পনা নিয়ে ক্যোয়ারী চালাচ্ছে। আমি এই পদ্ধতিটি ব্যবহার করে ধরা পড়েছি (একটি অর্ডার বাই যোগ করে)। এটি যখন অল্প সংখ্যক সারিগুলির সাথে কাজ করছিল তখন এটি ঠিকঠাক কাজ করেছিল তবে আরও ডেটা দিয়ে এসকিউএল সার্ভার একটি আলাদা পরিকল্পনা বেছে নিয়েছিল যার ফলশ্রুতিতে কোন আইকন ছাড়াই প্রথম আইটেমটি নির্বাচন করা হয়েছিল। অনিথ সেনের এই নিবন্ধটি দেখুন
fberber

17
এই পদ্ধতিটি একটি নির্বাচনী তালিকায় উপ-কোয়েরি হিসাবে বা কোথায়-ক্লজ হিসাবে ব্যবহার করা যাবে না কারণ এটি একটি টিএসকিউএল ভেরিয়েবল ব্যবহার করে। এই জাতীয় পরিস্থিতিতে আপনি @ রিতেশের প্রস্তাবিত পদ্ধতিগুলি ব্যবহার করতে পারেন
আর। শেরুরস

11
এটি সংক্ষিপ্তকরণের একটি নির্ভরযোগ্য পদ্ধতি নয়। এটি অসমর্থিত এবং ব্যবহার করা উচিত নয় (যেমন প্রতি মাইক্রোসফ্ট, সমর্থন . microsoft.com/en-us/kb/287515 , কানেক্ট.মাইক্রোসফট / এসকিউএল সার্ভার / ফিডব্যাক / বিবরণ / 704389 )। এটি সতর্কতা ছাড়াই পরিবর্তন করতে পারে। স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 5031204
মার্ক দুরদিন

452

এসকিউএল সার্ভার 2017+ এবং এসকিউএল অ্যাজুরি: STRING_AGG

এসকিউএল সার্ভারের পরবর্তী সংস্করণ দিয়ে শুরু করে, আমরা শেষ পর্যন্ত কোনও ভেরিয়েবল বা এক্সএমএল উইচরি অবলম্বন না করে সারিগুলি জুড়ে একত্রিত করতে পারি।

STRING_AGG (লেনদেন-এসকিউএল)

গ্রুপিং ছাড়াই

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 (নাম, ',') নির্বাচন করুন বিভাগ থেকে FROM (হিউম্যান রিসোর্সেস থেকে শীর্ষ 100000 নাম নির্বাচন করুন। নাম অনুসারে ডিপার্টমেন্টের অর্ডার) ডি;
রউদভেকে

362

XML data()এমএস এসকিউএল সার্ভারের কমান্ডের মাধ্যমে এখনও একটি পদ্ধতি প্রদর্শন করা হয়নি :

এফমন নামক একটি কলাম সহ নাম তালিকাভুক্ত নামক টেবিলটি ধরে নিন,

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 ** টি আশ্চর্যজনক না! যখন নিজেই কার্যকর করা হয়, যেমন আপনার উদাহরণ হিসাবে ফলাফলটি হাইপারলিঙ্ক হিসাবে ফর্ম্যাট করা হয়, যখন ক্লিক করা হয় (এসএসএমএসে) ডেটাযুক্ত একটি নতুন উইন্ডো খোলে, তবে বৃহত্তর ক্যোয়ারির অংশ হিসাবে ব্যবহার করার সময় এটি কেবল একটি স্ট্রিং হিসাবে উপস্থিত হয়। এটা কি স্ট্রিং? বা এটি কি এক্সএমএল যে অ্যাপ্লিকেশনটিতে এই ডেটাটি ব্যবহার করা হবে তার জন্য আমার আলাদা আচরণ করা উচিত?
বেন

10
এই পদ্ধতিটি এক্সএমএল <এবং> এর মতো অক্ষরগুলি থেকেও পালিয়ে যায়। সুতরাং, '<b>' + এফএনমে + '</ b>' নির্বাচন করে "& lt; b & gt; জন & lt; / b & gt; & lt; বি & gt; পল ..."
লুকা লানস্কে

8
ঝরঝরে সমাধান। আমি লক্ষ্য করছি যে আমি যুক্ত না করলেও + ', 'এটি প্রতিটি সংক্ষিপ্ত উপাদানগুলির মধ্যে একটি একক স্থান যুক্ত করে।
বাওদাদ

8
@ বোয়াদাদ এটি চুক্তির অংশ হিসাবে উপস্থিত বলে মনে হচ্ছে। আপনি একটি অতিরিক্ত টোকেন অক্ষর প্রতিস্থাপন দ্বারা workaround করতে পারেন। উদাহরণস্বরূপ, এটি যে কোনও দৈর্ঘ্যের জন্য নিখুঁত কমা- SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
বিস্মৃত

1
বাহ, প্রকৃতপক্ষে আমার পরীক্ষায় ডেটা () ব্যবহার করে এবং প্রতিস্থাপনটি ওয়ে এর চেয়ে বেশি পারফরম্যান্ট। সুপার অদ্ভুত।
এনআরিলিংহ

306

ইন SQL সার্ভার 2005

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

এসকিউএল সার্ভার ২০১ 2016-এ

আপনি ব্যবহার করতে পারেন 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

এবং ফলাফল হয়ে যাবে

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

এটি এমনকি আপনার ডেটাতে অবৈধ এক্সএমএল অক্ষরগুলিও কাজ করবে

'"},{"_":"'নিরাপদ কারন যদি আপনি ডাটা ধারণ '"},{"_":"',এটি পলান করা হবে"},{\"_\":\"

আপনি যে ', 'কোনও স্ট্রিং বিভাজকের সাথে প্রতিস্থাপন করতে পারেন


এবং এসকিউএল সার্ভারে 2017, অ্যাজুরে এসকিউএল ডেটাবেস

আপনি নতুন STRING_AGG ফাংশনটি ব্যবহার করতে পারেন


3
শীর্ষস্থানীয় দুটি অক্ষর নিক্স করতে STUFF ফাংশনটির ভাল ব্যবহার।
ডেভিড

3
আমার এই সমাধানটি সবচেয়ে ভাল লেগেছে, কারণ আমি সহজেই '<label>' যুক্ত করে একটি নির্বাচিত তালিকায় এটি ব্যবহার করতে পারি। @ রিতেশের সমাধান দিয়ে এটি কীভাবে করবেন তা সম্পর্কে আমি নিশ্চিত নই।
আর। শ্রেরস

13
এই গৃহীত উত্তর চেয়ে ভাল কারণ এই বিকল্পটি যেমন অ-পলায়নের এক্সএমএল reserverd অক্ষর পরিচালনা হয় <, >, &, ইত্যাদি যা FOR XML PATH('')স্বয়ংক্রিয়ভাবে অব্যাহতি হবে।
বেটটেক 21

এটি একটি দুর্দান্ত প্রতিক্রিয়া কারণ এটি সমস্যার সমাধান করেছে এবং এসকিউএল এর বিভিন্ন সংস্করণে জিনিসগুলি করার সর্বোত্তম উপায়গুলি সরবরাহ করে এখন আমি আশা করি আমি 2017 / অ্যাজুরি ব্যবহার করতে পারতাম
ক্রিস ওয়ার্ড

120

মাইএসকিউএলে একটি ফাংশন রয়েছে, GROUP_CONCAT () , যা আপনাকে একাধিক সারি থেকে মানগুলি সংযুক্ত করতে দেয় allows উদাহরণ:

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

@ গুলেম আপনি কী বলতে চাইছেন তা সম্পর্কে আমি পরিষ্কার নই, তবে এই ফাংশনটি কেবল আইটেমগুলির মধ্যে বিভাজক রাখে, পরে নয়। যদি উত্তরটি না হয় তবে আমি একটি নতুন প্রশ্ন পোস্ট করার পরামর্শ দেব।
ড্যারিল হেইন

আমার প্রয়োজনীয়তার জন্য @ ড্যারিলহেইন আমি উপরের মত বিভাজকটি ব্যবহার করেছি। তবে এটি আমাকে আউটপুটের একেবারে শেষে কিছু অক্ষর কেটে দেয়। এটি খুব অদ্ভুত এবং এটি একটি বাগ বলে মনে হচ্ছে। আমার কোনও সমাধান নেই, আমি কেবল একচেটিয়া হয়েছি।
gooleem

মূলত কাজ করে। দুটি জিনিস বিবেচনা: 1) যদি আপনার কলামটি একটি নয় CHAR, আপনি এটি নিক্ষেপ করা প্রয়োজন, যেমন মাধ্যমে GROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')2) যদি আপনি অনেক মান আসছে আছে, তবে আপনি বৃদ্ধি করা উচিত group_concat_max_lenযেমন লেখা stackoverflow.com/a/1278210/1498405
hardmooth

58

COALESCE ব্যবহার করুন - এখান থেকে আরও জানুন

উদাহরণস্বরূপ:

102

103

104

তারপরে স্ক্যালি সার্ভারে কোডের নিচে লিখুন,

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
এটি সত্যিই সেরা সমাধান আইএমও কারণ এটি এনএমএল উপস্থাপিত এনকোডিংয়ের বিষয়গুলি এড়িয়ে চলে। আমি ব্যবহার করেছি Declare @Numbers AS Nvarchar(MAX)এবং এটি ভাল কাজ করেছে। আপনি দয়া করে কেন এটি ব্যবহার না করার পরামর্শ দিচ্ছেন?
এভিলড্রি

7
এই সমাধানটি ইতিমধ্যে 8 বছর আগে পোস্ট করা হয়েছে! stackoverflow.com/a/194887/986862
আন্দ্রে

কেন এই কোয়েরি ফিরে আসে ??? সিরিলিকের পরিবর্তে প্রতীকগুলি? এটি কি কেবল আউটপুট ইস্যু?
আকমল সালিখভ

48

পোস্টগ্রিস অ্যারে দুর্দান্ত। উদাহরণ:

কিছু পরীক্ষার ডেটা তৈরি করুন:

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 সার্ভার , শুধুমাত্র MySQL
GoldBishop

46

ওরাকল 11 জি রিলিজ 2, লিস্ট্যাগ ফাংশন সমর্থন করে। ডকুমেন্টেশন এখানে

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.

সতর্কতা

ফলস্বরূপ স্ট্রিং 4000 টির বেশি অক্ষরের বেশি যাওয়ার সম্ভাবনা থাকলে এই ফাংশনটি বাস্তবায়নে সতর্ক হন। এটি ব্যতিক্রম ছুঁড়ে ফেলবে। যদি এটি হয় তবে আপনার ব্যতিক্রমটি পরিচালনা করতে হবে বা আপনার নিজের ফাংশনটি রোল করা উচিত যা যুক্ত হওয়া স্ট্রিংকে 4000 টির বেশি অক্ষরের উপরে যেতে বাধা দেয়।


1
ওরাকল এর পুরানো সংস্করণগুলির জন্য, wm_concat নিখুঁত। অ্যালেক্সের লিঙ্ক উপহারে এর ব্যবহারের ব্যাখ্যা দেওয়া হয়েছে। থ্যাঙ্কস অ্যালেক্স!
toscanelli

LISTAGGনিখুঁত কাজ করে! এখানে লিঙ্কযুক্ত দস্তাবেজটি কেবল পড়ুন। wm_concat12c সংস্করণ থেকে অপসারণ করা হয়েছে।
জিজ্ঞাসা করুন

34

এসকিউএল সার্ভার 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
আমার বিশ্বাস এই ব্যর্থ হলে মান যেমন এক্সএমএল চিহ্ন থাকা <বা &
স্যাম

28

বাড়িতে আমার এসকিউএল সার্ভারের অ্যাক্সেস নেই, সুতরাং আমি অনুমান করছি যে এখানে বাক্য গঠনটি রয়েছে তবে এটি কমবেশি:

DECLARE @names VARCHAR(500)

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

11
আপনার @ নামগুলি অ-শূন্য কিছুতে প্রবর্তন করতে হবে, অন্যথায় আপনি জুড়ে নুল পাবেন;
আপনারও

3
এই পদ্ধতির সাথে একমাত্র সমস্যা (যা আমি সর্বদা ব্যবহার করি) আপনি এটি এম্বেড করতে পারবেন না
এখিসিস

1
শীর্ষস্থানীয় স্থান থেকে মুক্তি পেতে ক্যোয়ারীটি এতে পরিবর্তন করুনSELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
টিয়ান ভ্যান হেরডেন

এছাড়াও, আপনাকে পরীক্ষা করতে হবে যে নামটি বাতিল নয়, আপনি এটি করে এটি করতে পারেন:SELECT @names = @names + ISNULL(' ' + Name, '')
ভিটা 1ij

28

একটি পুনরাবৃত্ত সিটিই সমাধান প্রস্তাব দেওয়া হয়েছিল, কিন্তু কোনও কোড সরবরাহ করা হয়নি। নীচের কোডটি একটি পুনরাবৃত্ত সিটিইর উদাহরণ। মনে রাখবেন যে ফলাফল প্রশ্নের সাথে মেলে, তথ্যের সাথে বর্ণিত বর্ণনার সাথে বেশ কিছু মেলে না , কারণ আমি ধরে নিয়েছি যে আপনি টেবিলের সমস্ত সারি নয়, সারিগুলির দলগুলিতে এই কাজটি করতে চান। টেবিলের সমস্ত সারি মিলে এটি পরিবর্তন করা পাঠকের অনুশীলন হিসাবে ছেড়ে দেওয়া হয়েছে।

;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
আক্কেল গুড়ুম জন্য: একটি অস্থায়ী basetable মধ্যে এই প্রশ্নের সাথে টিপে 12 সারি (3 কলাম), তারপর একটি recursive সাধারণ টেবিল এক্সপ্রেশন (rCTE) তৈরি করে এবং তারপর চ্যাপ্টা name 4 কমা দ্বারা পৃথক করা স্ট্রিং মধ্যে কলাম গ্রুপ এর idসে। প্রথম নজরে, আমি মনে করি এটি এসকিউএল সার্ভারের জন্য সর্বাধিক অন্যান্য সমাধানগুলির চেয়ে বেশি কাজ।
knb

2
@ কেএনবি: নিশ্চিত নয় যে এটি প্রশংসা, নিন্দা বা অবাক হওয়ার মতো কিনা। বেস টেবিলটি হ'ল কারণ আমি আমার উদাহরণগুলি বাস্তবে কাজ করতে পছন্দ করি, এটির প্রশ্নের সাথে আসলেই কিছু করার নেই।
jmoreno

26

আপনাকে এমন একটি ভেরিয়েবল তৈরি করতে হবে যা আপনার চূড়ান্ত ফলাফলটি ধারণ করবে এবং এর মধ্যে এটি নির্বাচন করবে।

সবচেয়ে সহজ সমাধান

DECLARE @char VARCHAR(MAX);

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

PRINT @char;

25

PostgreSQL 9.0 দিয়ে শুরু করা এটি বেশ সহজ:

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

9.0 এর আগের সংস্করণগুলিতে array_agg()hgmnz দ্বারা প্রদর্শিত হিসাবে ব্যবহার করা যেতে পারে


টাইপ পাঠ্যের নয় এমন কলামগুলি করতে এটির জন্য আপনাকে টাইপ কাস্ট যুক্ত করতে হবে:SELECT string_agg(non_text_type::text, ',') FROM table
টরবেন কোহলমিয়ার

@ টরবেন কোহলমিয়ার: আপনার কেবল অক্ষরযুক্ত কলামগুলির জন্য প্রয়োজন (যেমন পূর্ণসংখ্যা, দশমিক)। এটা তোলে মাত্র কাজ করে জরিমানা varcharবাchar
a_horse_with_no_name


18

এক্সএমএল ব্যবহার করে সারিগুলি কমা দিয়ে আলাদা করতে সহায়তা করেছিল। অতিরিক্ত কমা জন্য আমরা এসকিউএল সার্ভারের প্রতিস্থাপন ফাংশনটি ব্যবহার করতে পারি। কমা যুক্ত করার পরিবর্তে, এএস 'ডেটা ()' এর ব্যবহারটি সারিগুলিকে ফাঁকা স্থানের সাথে একত্রিত করবে, যা পরে নীচের লিখিত সিনট্যাক্স হিসাবে কমা দ্বারা প্রতিস্থাপন করা যেতে পারে।

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

2
এটি আমার মতামত এখানে সেরা উত্তর। আপনার যখন অন্য টেবিলে যোগ দিতে হবে তখন ডিক্লেয়ার ভেরিয়েবলের ব্যবহার ভাল নয় এবং এটি দুর্দান্ত এবং সংক্ষিপ্ত। ভাল কাজ.
ডেভিড রুসেল

7
FName ডেটাতে ইতিমধ্যে স্পেস থাকলে এটি ভাল কাজ করছে না, উদাহরণস্বরূপ "আমার নাম"
বিনবল

সত্যিই এটি আমার জন্য এমএস-এসকিএল ২০১ on-তে কাজ করছে, এক্সএমএল পাথ ('')), '', 'ব্র্যান্ড থেকে আইডি আইএন (1,2,3,4) থেকে' রিপ্লেস ('নেম এএস' ডেটা () নির্বাচন করুন Select , ') সমস্ত ব্র্যান্ড হিসাবে
রেজওয়ানুল রেজা

17

কোনও অতিরিক্ত কমা ছাড়াই ব্যবহারের জন্য প্রস্তুত সমাধান:

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

একটি খালি তালিকা ফলাফলের ফলাফল করবে। সাধারণত আপনি তালিকাটি একটি টেবিল কলাম বা প্রোগ্রাম ভেরিয়েবলের মধ্যে সন্নিবেশ করান: আপনার প্রয়োজনের সাথে 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)

এটি শুরুতে বিপথগামী কমা রাখে।

তবে, আপনার যদি অন্য কলামগুলির প্রয়োজন হয় বা সিএসভিতে কোনও শিশু টেবিলের দরকার হয় তবে এটিকে একটি স্কেলার ব্যবহারকারী সংজ্ঞায়িত ক্ষেত্রে (ইউডিএফ) মোড়ানো দরকার।

আপনিও নির্বাচন বিভাগে প্রাসঙ্গিক সাবকিউরি হিসাবে এক্সএমএল পাথটি ব্যবহার করতে পারেন (তবে গুগল ঘরে বসে স্টাফ না করায় আমাকে আবার কাজ করা পর্যন্ত অপেক্ষা করতে হবে :-)


10

অন্যান্য উত্তরের সাথে, উত্তরটি পড়ছেন এমন ব্যক্তিকে অবশ্যই একটি নির্দিষ্ট ডোমেন টেবিল যেমন যানবাহন বা শিক্ষার্থী সম্পর্কে সচেতন হতে হবে। কোনও সমাধান পরীক্ষা করার জন্য টেবিলটি অবশ্যই ডেটা দিয়ে তৈরি এবং পপুলেট করা উচিত।

নীচে একটি উদাহরণ রয়েছে যা এসকিউএল সার্ভার "ইনফরমেশন_শেমা.কলামগুলি" সারণী ব্যবহার করে। এই সমাধানটি ব্যবহার করে কোনও টেবিল তৈরি বা ডেটা যুক্ত করার দরকার নেই। এই উদাহরণটি ডাটাবেসের সমস্ত সারণীর জন্য কমা নামের পৃথক কলামের নামের তালিকা তৈরি করে।

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

ওরাকল ডিবি-র জন্য, এই প্রশ্নটি দেখুন: কীভাবে একাধিক সারি একটি সঞ্চিত প্রক্রিয়া তৈরি না করে ওরাকলিতে একটিতে সংযুক্ত করা যায়?

ওরাকল 11 জি রিলিজ 2 এবং এর পরে উপলব্ধ বিল্ট-ইন লিস্টাগজি () ফাংশনটি ব্যবহার করে @ এমমানুয়েল দ্বারা সেরা উত্তরটি উপস্থিত হতে পারে।

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

@ ব্যবহারকারী 76292952 হিসাবে উল্লেখ করা হয়েছে, এবং ওরাকল এর ডকুমেন্টেশন অনুযায়ী http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , ডাব্লুএম_কনক্যাট () ফাংশনও একটি বিকল্প। এটি স্থিতিশীল বলে মনে হয়, তবে ওরাকল স্পষ্টভাবে কোনও অ্যাপ্লিকেশন এসকিউএল এর জন্য এটি ব্যবহার করার বিরুদ্ধে সুপারিশ করে, তাই আপনার নিজের ঝুঁকিতে ব্যবহার করুন।

তা ছাড়া আপনার নিজের ফাংশনটি লিখতে হবে; উপরের ওরাকল নথিতে এটি কীভাবে করা যায় সে সম্পর্কে একটি গাইড রয়েছে।


7

নাল মান এড়ানোর জন্য আপনি কনক্যাট () ব্যবহার করতে পারেন

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

কনক্যাট কেন কাজ করে তা জেনে ভাল লাগবে । এমএসডিএন-এর একটি লিঙ্কটি দুর্দান্ত হবে।
বিপরীত ইঞ্জিনিয়ার

7

আমি ডানার উত্তরটির কমনীয়তা পছন্দ করেছি । শুধু এটি সম্পূর্ণ করতে চেয়েছিলেন।

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

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

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

আপনি যদি শেষ দুটি চিহ্ন ',' মুছে ফেলছেন তবে আপনাকে নামের পরে ',' যুক্ত করতে হবে ('নির্বাচন করুন name @ নামগুলি = \ @ নাম + নাম +', 'নাম থেকে')। এইভাবে সর্বশেষ দুটি অক্ষর সর্বদা ',' থাকবে।
JT_

আমার ক্ষেত্রে আমার শীর্ষস্থানীয় কমা থেকে মুক্তি পাওয়ার দরকার ছিল তাই কোয়েরিটি পরিবর্তন করে SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Namesফেলুন আপনাকে পরে এটি কেটে ফেলতে হবে না।
টিয়ান ভ্যান হেরডেন

6

এই উত্তরের জন্য সার্ভারে কাজ করার জন্য কিছু সুযোগ সুবিধা প্রয়োজন।

সমাবেশগুলি আপনার জন্য একটি ভাল বিকল্প। এখানে অনেকগুলি সাইট রয়েছে যা এটি কীভাবে তৈরি করা যায় তা ব্যাখ্যা করে। এক আমি মনে করি খুব ভাল ব্যাখ্যা করা হয় এই হল এক

আপনি যদি চান তবে আমি ইতিমধ্যে সমাবেশ তৈরি করেছি এবং এখানে ডিএলএল ডাউনলোড করা সম্ভব ।

একবার এটি ডাউনলোড হয়ে গেলে আপনার এসকিউএল সার্ভারে আপনাকে নিম্নলিখিত স্ক্রিপ্টটি চালাতে হবে:

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 ত্রুটি। এর জন্য অ্যাসেমব্লি ব্যবহার করা ওভারকিল। এসকিউএল সার্ভারের জন্য সেরা উত্তর দেখুন ।
প্রতিবাদী

6

মাইএসকিউএল সম্পূর্ণ উদাহরণ:

আমাদের এমন ব্যবহারকারী রয়েছে যার অনেকগুলি ডেটা থাকতে পারে এবং আমরা একটি আউটপুট পেতে চাই, যেখানে আমরা সমস্ত ব্যবহারকারীর একটি তালিকাতে ডেটা দেখতে পাব:

ফলাফল:

___________________________
| 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

আমি সাধারণত এসকিউএল সার্ভারে স্ট্রিংগুলি সংহত করতে এই জাতীয় নির্বাচন ব্যবহার করি:

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

এটি আমার জন্য কাজ করেছে ( স্কিল সার্ভার 2016 ):

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

উত্সটি এখানে: https://www.mytecbit.com/

এবং মাইএসকিএল এর সমাধান (যেহেতু এই পৃষ্ঠাটি মাইএসকিএল এর জন্য গুগলে প্রদর্শিত হচ্ছে)

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

মাইএসকিএল ডকুমেন্টেশন থেকে



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
দুর্ভাগ্যক্রমে এই আচরণটি আনুষ্ঠানিকভাবে সমর্থিত বলে মনে হচ্ছে না। এমএসডিএন বলছে: "যদি কোনও নির্বাচনের তালিকায় কোনও ভেরিয়েবলকে উল্লেখ করা হয়, তবে এটি একটি স্কেলারের মান বরাদ্দ করা উচিত বা সেলেক্ট স্টেটমেন্টটি কেবল একটি সারিতে ফিরবে।" এবং এমন কিছু লোক রয়েছে যারা সমস্যাগুলি পর্যবেক্ষণ করেছেন: sqlmag.com/sql-server/m Multi
row-
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.