কিভাবে আমি পাব:
id Name Value
1 A 4
1 B 8
2 C 9
প্রতি
id Column
1 A:4, B:8
2 C:9
কিভাবে আমি পাব:
id Name Value
1 A 4
1 B 8
2 C 9
প্রতি
id Column
1 A:4, B:8
2 C:9
উত্তর:
কোনও কার্সর, WHILE লুপ বা ব্যবহারকারী-সংজ্ঞায়িত ফাংশন প্রয়োজন ।
ফরএম এক্সএমএল এবং পথের সাথে সৃজনশীল হওয়া দরকার।
[দ্রষ্টব্য: এই সমাধানটি কেবল এসকিউএল 2005 এবং তার পরে কাজ করে। মূল প্রশ্নটি ব্যবহারের সংস্করণটি নির্দিষ্ট করে নি]]
CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)
SELECT
[ID],
STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
এটি যদি এসকিউএল সার্ভার 2017 বা এসকিউএল সার্ভার ভিনেক্সট হয়, এসকিউএল অ্যাজুরি আপনি নীচে হিসাবে স্ট্রিং_এজি ব্যবহার করতে পারেন:
select id, string_agg(concat(name, ':', [value]), ', ')
from #YourTable
group by id
এক্সএমএল পাথটি ব্যবহার করা আপনার প্রত্যাশা মতো পুরোপুরি একত্রী হতে পারে না ... এটি "&" এর সাথে "& amp" প্রতিস্থাপন করবে; এবং এছাড়াও গণ্ডগোল হবে <" and ">
... সম্ভবত কিছু অন্যান্য জিনিস, নিশ্চিত নয় ... তবে আপনি এটি চেষ্টা করতে পারেন
আমি এটির জন্য একটি পরিশ্রম জুড়ে এসেছি ... আপনাকে প্রতিস্থাপন করতে হবে:
FOR XML PATH('')
)
সঙ্গে:
FOR XML PATH(''),TYPE
).value('(./text())[1]','VARCHAR(MAX)')
... বা NVARCHAR(MAX)
যদি আপনি যা ব্যবহার করছেন তা যদি হয়।
কেন জাহান্নামের SQL
একত্রীকৃত কার্যকারিতা নেই? এটি একটি পিটিএ
যখন আমি স্ট্রিং স্পেস এবং বিশেষ এক্সএমএল অক্ষর (ধারণকারী সাথে কাজ করার জন্য কেভিন ফেয়ারচাইল্ড এর পরামর্শ রূপান্তর চেষ্টা আমি সমস্যার একটি দম্পতি গাড়ীতে আঘাত &
, <
, >
) যা এনকোড করা হয়।
আমার কোডের চূড়ান্ত সংস্করণ (যা মূল প্রশ্নের উত্তর দেয় না তবে কারওর পক্ষে কার্যকর হতে পারে) এর মত দেখাচ্ছে:
CREATE TABLE #YourTable ([ID] INT, [Name] VARCHAR(MAX), [Value] INT)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'Oranges & Lemons',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'1 < 2',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)
SELECT [ID],
STUFF((
SELECT ', ' + CAST([Name] AS VARCHAR(MAX))
FROM #YourTable WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE
/* Use .value to uncomment XML entities e.g. > < etc*/
).value('.','VARCHAR(MAX)')
,1,2,'') as NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
স্থানকে একটি ডিলিমিটার হিসাবে ব্যবহার করার পরিবর্তে এবং সমস্ত স্পেসকে কমা দিয়ে প্রতিস্থাপনের পরিবর্তে, এটি প্রতিটি মানকে একটি কমা এবং স্পেসকে পূর্ব-পেন্ড করে তারপর STUFF
প্রথম দুটি অক্ষর অপসারণ করতে ব্যবহার করে।
এক্সএমএল এনকোডিং টিওয়াইপিই নির্দেশিকা ব্যবহার করে স্বয়ংক্রিয়ভাবে যত্ন নেওয়া হয় ।
এসকিএল সার্ভার 2005 এবং তারপরে ব্যবহার করে অন্য একটি বিকল্প
---- test data
declare @t table (OUTPUTID int, SCHME varchar(10), DESCR varchar(10))
insert @t select 1125439 ,'CKT','Approved'
insert @t select 1125439 ,'RENO','Approved'
insert @t select 1134691 ,'CKT','Approved'
insert @t select 1134691 ,'RENO','Approved'
insert @t select 1134691 ,'pn','Approved'
---- actual query
;with cte(outputid,combined,rn)
as
(
select outputid, SCHME + ' ('+DESCR+')', rn=ROW_NUMBER() over (PARTITION by outputid order by schme, descr)
from @t
)
,cte2(outputid,finalstatus,rn)
as
(
select OUTPUTID, convert(varchar(max),combined), 1 from cte where rn=1
union all
select cte2.outputid, convert(varchar(max),cte2.finalstatus+', '+cte.combined), cte2.rn+1
from cte2
inner join cte on cte.OUTPUTID = cte2.outputid and cte.rn=cte2.rn+1
)
select outputid, MAX(finalstatus) from cte2 group by outputid
Http://groupconcat.codeplex.com থেকে এসকিউএলসিআরআর সমষ্টিগুলি ইনস্টল করুন
তারপরে আপনি যে ফলাফলটি চেয়েছিলেন তা পেতে আপনি এই জাতীয় কোড লিখতে পারেন:
CREATE TABLE foo
(
id INT,
name CHAR(1),
Value CHAR(1)
);
INSERT INTO dbo.foo
(id, name, Value)
VALUES (1, 'A', '4'),
(1, 'B', '8'),
(2, 'C', '9');
SELECT id,
dbo.GROUP_CONCAT(name + ':' + Value) AS [Column]
FROM dbo.foo
GROUP BY id;
এসকিউএল সার্ভার ২০০৫ এবং পরে আপনাকে নিজের কাস্টম সমষ্টিগত ফাংশনগুলি তৈরি করার অনুমতি দেয় , এতে কনটেনটেশন-এর মতো জিনিসগুলি যুক্ত রয়েছে - লিঙ্কযুক্ত নিবন্ধের নীচে নমুনাটি দেখুন।
আট বছর পরে ... মাইক্রোসফ্ট এসকিউএল সার্ভার vNext ডেটাবেস ইঞ্জিন অবশেষে সরাসরি গোষ্ঠীযুক্ত স্ট্রিং উপসংহার সমর্থন করার জন্য লেনদেন-এসকিউএল বাড়িয়েছে। সম্প্রদায়টির প্রযুক্তিগত পূর্বরূপ সংস্করণ ১.০ STRING_AGG ফাংশন যুক্ত করেছে এবং সিটিপি 1.1 এ STRING_AGG ফাংশনের জন্য WITHIN GROUP ধারা যুক্ত করেছে।
তথ্যসূত্র: https://msdn.microsoft.com/en-us/library/mt775028.aspx
এটি কেভিন ফেয়ারচাইল্ডের পোস্টের (কেবল উপায় দ্বারা খুব চালাক) একটি সংযোজন। আমি এটি একটি মন্তব্য হিসাবে যোগ করতে হবে, কিন্তু আমার এখনও পর্যাপ্ত পয়েন্ট নেই :)
আমি এই ধারণাটি আমি যে দৃশ্যে কাজ করছি তার জন্য ব্যবহার করছিলাম, তবে যে আইটেমগুলিতে আমি একত্রিত হয়েছি সেখানে স্পেস রয়েছে। সুতরাং আমি ডিলিমিটার হিসাবে স্পেস ব্যবহার না করার জন্য কোডটি কিছুটা সংশোধন করেছি।
আবার ধন্যবাদ কুল কাজের জন্য কেভিন!
CREATE TABLE #YourTable ( [ID] INT, [Name] CHAR(1), [Value] INT )
INSERT INTO #YourTable ([ID], [Name], [Value]) VALUES (1, 'A', 4)
INSERT INTO #YourTable ([ID], [Name], [Value]) VALUES (1, 'B', 8)
INSERT INTO #YourTable ([ID], [Name], [Value]) VALUES (2, 'C', 9)
SELECT [ID],
REPLACE(REPLACE(REPLACE(
(SELECT [Name] + ':' + CAST([Value] AS VARCHAR(MAX)) as A
FROM #YourTable
WHERE ( ID = Results.ID )
FOR XML PATH (''))
, '</A><A>', ', ')
,'<A>','')
,'</A>','') AS NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
ওরাকলে আপনি তালিকাবদ্ধ সমষ্টি ফাংশনটি ব্যবহার করতে পারেন।
আসল রেকর্ড
name type
------------
name1 type1
name2 type2
name2 type3
SQL
SELECT name, LISTAGG(type, '; ') WITHIN GROUP(ORDER BY name)
FROM table
GROUP BY name
ফলাফল
name type
------------
name1 type1
name2 type2; type3
এই ধরণের প্রশ্নটি এখানে প্রায়শই জিজ্ঞাসা করা হয় এবং সমাধানটি অন্তর্নিহিত প্রয়োজনীয়তার উপর অনেক বেশি নির্ভর করে:
https://stackoverflow.com/search?q=sql+pivot
এবং
https://stackoverflow.com/search?q=sql+concatenate
সাধারণত, গতিশীল এসকিএল, কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন বা কার্সার ছাড়াই এটি করার কোনও এসকিউএল-কেবল উপায় নেই।
কেবল ক্যাড যা বলেছেন তাতে যুক্ত করার জন্য, এটি সাধারণত একটি ফ্রন্ট-এন্ড ডিসপ্লে জিনিস এবং তাই সেখানে পরিচালনা করা উচিত। আমি জানি যে কখনও কখনও ফাইল এক্সপোর্ট বা অন্যান্য "এসকিউএল কেবলমাত্র" সমাধানগুলির মতো জিনিসগুলির জন্য এসকিউএলে 100% কিছু লেখা সহজ হয় তবে বেশিরভাগ সময় এই প্রদর্শনীর স্তরটি আপনার প্রদর্শন স্তরে পরিচালনা করা উচিত।
কার্সারের দরকার নেই ... কিছুক্ষণ লুপই যথেষ্ট is
------------------------------
-- Setup
------------------------------
DECLARE @Source TABLE
(
id int,
Name varchar(30),
Value int
)
DECLARE @Target TABLE
(
id int,
Result varchar(max)
)
INSERT INTO @Source(id, Name, Value) SELECT 1, 'A', 4
INSERT INTO @Source(id, Name, Value) SELECT 1, 'B', 8
INSERT INTO @Source(id, Name, Value) SELECT 2, 'C', 9
------------------------------
-- Technique
------------------------------
INSERT INTO @Target (id)
SELECT id
FROM @Source
GROUP BY id
DECLARE @id int, @Result varchar(max)
SET @id = (SELECT MIN(id) FROM @Target)
WHILE @id is not null
BEGIN
SET @Result = null
SELECT @Result =
CASE
WHEN @Result is null
THEN ''
ELSE @Result + ', '
END + s.Name + ':' + convert(varchar(30),s.Value)
FROM @Source s
WHERE id = @id
UPDATE @Target
SET Result = @Result
WHERE id = @id
SET @id = (SELECT MIN(id) FROM @Target WHERE @id < id)
END
SELECT *
FROM @Target
আসুন খুব সহজ:
SELECT stuff(
(
select ', ' + x from (SELECT 'xxx' x union select 'yyyy') tb
FOR XML PATH('')
)
, 1, 2, '')
এই লাইনটি প্রতিস্থাপন করুন:
select ', ' + x from (SELECT 'xxx' x union select 'yyyy') tb
আপনার প্রশ্নের সাথে।
কোনও ক্রস উত্তরগুলি প্রয়োগ করে না, এক্সএমএল উত্তোলনেরও প্রয়োজন নেই। কেভিন ফেয়ারচাইল্ড যা লিখেছিলেন তার কিছুটা আলাদা সংস্করণ এখানে। আরও জটিল প্রশ্নগুলিতে এটি ব্যবহার করা আরও দ্রুত এবং সহজ:
select T.ID
,MAX(X.cl) NameValues
from #YourTable T
CROSS APPLY
(select STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = T.ID)
FOR XML PATH(''))
,1,2,'') [cl]) X
GROUP BY T.ID
গোষ্ঠীটির মধ্যে বেশিরভাগই একটি আইটেম থাকে তবে আপনি নিম্নলিখিত উপায়ে পারফরম্যান্সকে উন্নত করতে পারেন:
SELECT
[ID],
CASE WHEN MAX( [Name]) = MIN( [Name]) THEN
MAX( [Name]) NameValues
ELSE
STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
END
FROM #YourTable Results
GROUP BY ID
রিপ্লেস ফাংশন এবং জসন পাঠের জন্য ব্যবহার করে
SELECT T3.DEPT, REPLACE(REPLACE(T3.ENAME,'{"ENAME":"',''),'"}','') AS ENAME_LIST
FROM (
SELECT DEPT, (SELECT ENAME AS [ENAME]
FROM EMPLOYEE T2
WHERE T2.DEPT=T1.DEPT
FOR JSON PATH,WITHOUT_ARRAY_WRAPPER) ENAME
FROM EMPLOYEE T1
GROUP BY DEPT) T3
নমুনা ডেটা এবং আরও উপায়ের জন্য এখানে ক্লিক করুন
আপনি যদি ক্লার সক্ষম করে থাকেন তবে আপনি গিটহাব থেকে গ্রুপ_কনক্যাট লাইব্রেরি ব্যবহার করতে পারেন
GROUP_CONCAT()
সামগ্রিক ফাংশন সহ সহজেই সমাধান করা হয় তবে মাইক্রোসফ্ট এসকিউএল সার্ভারে এটি সমাধান করা আরও বিশ্রী। সহায়তার জন্য নিম্নলিখিত এসও প্রশ্নটি দেখুন: " সম্পর্কের ভিত্তিতে একটি রেকর্ডের বিপরীতে একাধিক রেকর্ড কীভাবে পাবেন? "