স্কুল সার্ভারে কীভাবে স্টাফ এবং 'এক্সএমএল পাথের জন্য' কাজ করে


367

সারণীটি হ'ল:

+----+------+
| Id | Name |
+----+------+    
| 1  | aaa  |
| 1  | bbb  |
| 1  | ccc  |
| 1  | ddd  |
| 1  | eee  |
+----+------+

প্রয়োজনীয় আউটপুট:

+----+---------------------+
| Id |        abc          |
+----+---------------------+ 
|  1 | aaa,bbb,ccc,ddd,eee |
+----+---------------------+

প্রশ্ন:

SELECT ID, 
    abc = STUFF(
                 (SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
               ) 
FROM temp1 GROUP BY id

এই ক্যোয়ারী সঠিকভাবে কাজ করছে। তবে এটি কীভাবে কাজ করে বা এটি করার জন্য অন্য কোনও বা সংক্ষিপ্ত পথ রয়েছে তা কেবল আমার ব্যাখ্যা দরকার।

আমি এটি বুঝতে খুব বিভ্রান্ত হয়ে পড়ছি।


1
আরও দেখুন stackoverflow.com/questions/21623593/...
ChrisF

1
এটি বাস্তব জীবনে কাজ করে দেখার জন্য আমি এর জন্য একটি স্ক্যলফিডাল পৃষ্ঠা তৈরি করেছি । আশা করি এটি অন্যকে সহায়তা করবে।
সাবুনকু

1
^ সম্ভবত IDবিভিন্ন সত্তার আলাদা টেবিলে এটি অনন্য এবং এই টেবিলটি তাদের নিজস্ব জিনিসগুলি সংরক্ষণ করছে।
নিক রোল্যান্ডো

এই সন্ধানটির কয়েকটি কাজ করে না যদি কয়েকটি সারিতে আলাদা আইডি থাকে। যেমন 'ডিডিডি' এবং '
আইই'র

10
আমি কোথায় ভুল হয়েছি তা দেখার জন্য এই পৃষ্ঠায় আমার মাসিক দেখার সময়
টেলর অ্যাকলে

উত্তর:


683

এটা যেভাবে কাজ করে:

1. এক্সএমএল জন্য এক্সএমএল উপাদান স্ট্রিং পান

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

SELECT ',' + name 
              FROM temp1
              FOR XML PATH ('')

একটি ফাঁকা স্ট্রিংয়ে (এক্সএমএল পাঠ ('')) এর মাধ্যমে, আমরা পরিবর্তে নিম্নলিখিতটি পাই:

,aaa,bbb,ccc,ddd,eee

২. এসটিইউএফএফের সাহায্যে শীর্ষস্থানীয় কমা সরান

এসটিইউএফএফ স্টেটমেন্টটি আক্ষরিকভাবে একটি স্ট্রিংটিকে অন্য স্ট্রিংয়ে "স্টাফস" করে, প্রথম স্ট্রিংয়ের মধ্যে অক্ষরগুলি প্রতিস্থাপন করে however আমরা তবে মানগুলির ফলাফলের তালিকার প্রথম অক্ষরটি সরিয়ে ফেলতে এটি কেবল ব্যবহার করছি।

SELECT abc = STUFF((
            SELECT ',' + NAME
            FROM temp1
            FOR XML PATH('')
            ), 1, 1, '')
FROM temp1

এর পরামিতিগুলি হ'ল STUFF:

  • স্ট্রিংটি "স্টাফ করা" হবে (আমাদের ক্ষেত্রে একটি শীর্ষস্থানীয় কমা সহ নামের সম্পূর্ণ তালিকা)
  • অক্ষর মুছতে এবং সন্নিবেশ করা শুরু করার অবস্থানটি (1, আমরা একটি ফাঁকা স্ট্রিংয়ের মধ্যে স্টাফ করছি)
  • মুছে ফেলতে অক্ষরের সংখ্যা (1, শীর্ষস্থানীয় কমা হ'ল)

সুতরাং আমরা এখানে দিয়ে শেষ:

aaa,bbb,ccc,ddd,eee

৩. সম্পূর্ণ তালিকা পেতে আইডিতে যোগ দিন

পরবর্তী আমরা নাম সহ আইডির তালিকা পেতে, কেবলমাত্র টেম্প টেবিলের আইডি তালিকার সাথে এটিতে যোগদান করব:

SELECT ID,  abc = STUFF(
             (SELECT ',' + name 
              FROM temp1 t1
              WHERE t1.id = t2.id
              FOR XML PATH (''))
             , 1, 1, '') from temp1 t2
group by id;

এবং আমরা আমাদের ফলাফল:

-----------------------------------
| Id        | Name                |
|---------------------------------|
| 1         | aaa,bbb,ccc,ddd,eee |
-----------------------------------

আশাকরি এটা সাহায্য করবে!


57
আপনার মাইক্রোসফ্টের ডকুমেন্টেশন টিমের হয়ে কাজ করা উচিত (যদি থাকে)
Fandango68

55
@ ফান্ডাঙ্গো 68৮, @ ফুটবোলফ্যান - তিনি মাইক্রোসফ্টের ডকুমেন্টেশন দলের হয়ে কাজ করতে পারবেন না। তার ব্যাখ্যা খুব স্পষ্ট এবং খুব সরাসরি। ;-)
ক্রিস

1
@ ক্রিসপ্রোসর আমি সম্মত ওরাকল 11 LISTAGGজিআর 2-তে ফাংশন প্রবর্তন করে মাইক্রোসফ্টের চেয়ে এগিয়ে ছিল ওরাকল। আমি সেই দিনগুলিতে সেই কার্যকারিতাটি মিস করি যেখানে পরিবর্তে আমাকে এটি ব্যবহার করতে হবে। techonthenet.com/oracle/funitions/listagg.php
ফুটবলফ্যান

2
হ্যালো. পদক্ষেপ 1 এ, আপনি যদি করেন: এক্সএমএল পাঠ ('') এর জন্য টেম্প 1 থেকে নাম নির্বাচন করুন ... আপনি <name>aaa//name> <name> বিবিবি </ name> ... ইত্যাদি পেয়েছেন ... আমি করিনি ' প্রথমে এটি বুঝতে পারবেন না ... এটি নির্বাচন '' + + নাম ... ইত্যাদিতে পরিবর্তন করা ... ট্যাগগুলি সরান।
কেভিনভিক্টর

1
@ ক্রিসপ্রোসর - সিবাস এএসএ listকয়েক দশক ধরে একটি কাজ করেছে। দুর্ভাগ্যক্রমে মাইক্রোসফ্ট পরিবর্তে সিবাজের এএসইতে এসকিউএল সার্ভার ভিত্তিক, এবং গত বছর পর্যন্ত কোনও তালিকা কার্যক্রমে বিরক্ত করে না। আমি সম্মতি জানাই - এটি মনের মধ্যে উদ্বেগজনক। এবং তারপরে তারা করে, তারা এটি কল করে string_agg। আমি ভাবলাম listখুব সুস্পষ্ট ছিল।
youcantryreachingme

75

এই নিবন্ধটি এসকিউএল-তে স্ট্রাক্টকেটেনটিংয়ের বিভিন্ন উপায়ে কভার করেছে, এতে আপনার কোডের একটি উন্নত সংস্করণ রয়েছে যা এক্সএমএল-সংমিশ্রিত মানগুলিকে এনকোড করে না।

SELECT ID, abc = STUFF
(
    (
        SELECT ',' + name
        FROM temp1 As T2
        -- You only want to combine rows for a single ID here:
        WHERE T2.ID = T1.ID
        ORDER BY name
        FOR XML PATH (''), TYPE
    ).value('.', 'varchar(max)')
, 1, 1, '')
FROM temp1 As T1
GROUP BY id

কী হচ্ছে তা বুঝতে, অভ্যন্তরীণ কোয়েরি দিয়ে শুরু করুন:

SELECT ',' + name
FROM temp1 As T2
WHERE T2.ID = 42 -- Pick a random ID from the table
ORDER BY name
FOR XML PATH (''), TYPE

যেহেতু আপনি উল্লেখ করছেন FOR XML, আপনি একটি একক সারি পাবেন যা একটি এক্সএমএল খণ্ড রয়েছে যা সমস্ত সারিকে উপস্থাপন করে।

যেহেতু আপনি প্রথম কলামের জন্য কোনও কলামের নাম নির্দিষ্ট করে নেই, প্রতিটি সারি একটি এক্সএমএল উপাদানগুলিতে ব্র্যাককেটে উল্লিখিত নামের সাথে আবৃত হবে FOR XML PATH। উদাহরণস্বরূপ, যদি আপনি FOR XML PATH ('X')থাকতেন তবে আপনি একটি এক্সএমএল ডকুমেন্ট পাবেন যা দেখতে দেখতে:

<X>,aaa</X>
<X>,bbb</X>
...

তবে, যেহেতু আপনি কোনও উপাদানটির নাম নির্দিষ্ট করেননি, আপনি কেবল মানগুলির একটি তালিকা পাবেন:

,aaa,bbb,...

.value('.', 'varchar(max)')কেবল ফলে এক্সএমএল টুকরা থেকে মান আহরণ, কোনো "বিশেষ" অক্ষর এক্সএমএল-এনকোডিং ছাড়া। আপনার কাছে এখন এমন একটি স্ট্রিং রয়েছে যা দেখে মনে হচ্ছে:

',aaa,bbb,...'

এর পরে STUFFফাংশনটি আপনাকে চূড়ান্ত ফলাফল দেয় যা নেতৃস্থানীয় কমা সরিয়ে দেয়:

'aaa,bbb,...'

এটি প্রথম নজরে বেশ বিভ্রান্ত দেখাচ্ছে, তবে এটি অন্যান্য বিকল্পগুলির তুলনায় বেশ ভাল পারফরম্যান্সের ঝোঁক দেয়।


2
আপনার প্রশ্নের মধ্যে টাইপ ব্যবহার কি। আমি মনে করি এটি সংজ্ঞায়িত করার জন্য, এক্সএমএল পাথের ফলাফলটি মূল্যবান হবে (ভুল হলে এটি ব্যাখ্যা করবেন না)।
পুনেত চাওলা

8
@PuneetChawla: ডিরেক্টিভের বলে এসকিউএল ব্যবহার করে তথ্য ফিরে যাওয়ার ধরন। এটি ছাড়া, ডেটা হিসাবে ফিরে আসে । কলামে যদি বিশেষ অক্ষর থাকে তবে এক্সএমএল-এনকোডিং সমস্যাগুলি এড়াতে এটি এখানে ব্যবহৃত হয় । TYPExmlnvarchar(max)name
রিচার্ড ডেমিং

2
@ বারলপ: সিম্পলটাল্ক নিবন্ধটি যেমন ব্যাখ্যা করেছে, আপনি যদি ড্রপ করেন TYPEএবং .value('.', 'varchar(max)'), তারপরে আপনি এক্সএমএল-এনকোডেড সত্তাগুলির সাথে পরিণতিতে শেষ করতে পারেন।
রিচার্ড ডেমিং

1
@ রিচার্ডডিমিং এর অর্থ কি এই ডেটাতে অ্যাঙ্গেল বন্ধনী রয়েছে বা থাকতে পারে?
বারলপ

1
তবে, যেহেতু আপনি কোনও উপাদানটির নাম নির্দিষ্ট করেন নি, আপনি কেবল মানগুলির একটি তালিকা পান , এটি অন্তর্দৃষ্টি আমি অনুপস্থিত ছিল। ধন্যবাদ.
অ্যাডাম

44

PATH মোডটি একটি নির্বাচিত ক্যোয়ারী থেকে এক্সএমএল তৈরিতে ব্যবহৃত হয়

1. SELECT   
       ID,  
       Name  
FROM temp1
FOR XML PATH;  

Ouput:
<row>
<ID>1</ID>
<Name>aaa</Name>
</row>

<row>
<ID>1</ID>
<Name>bbb</Name>
</row>

<row>
<ID>1</ID>
<Name>ccc</Name>
</row>

<row>
<ID>1</ID>
<Name>ddd</Name>
</row>

<row>
<ID>1</ID>
<Name>eee</Name>
</row>

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

রোউসেটের প্রতিটি সারিটির জন্য একটি ট্যাগ যুক্ত করা হয়।

2.
SELECT   
       ID,  
       Name  
FROM temp1
FOR XML PATH('');

Ouput:
<ID>1</ID>
<Name>aaa</Name>
<ID>1</ID>
<Name>bbb</Name>
<ID>1</ID>
<Name>ccc</Name>
<ID>1</ID>
<Name>ddd</Name>
<ID>1</ID>
<Name>eee</Name>

পদক্ষেপ 2 এর জন্য: আপনি যদি শূন্য দৈর্ঘ্যের স্ট্রিং নির্দিষ্ট করেন তবে মোড়কের উপাদানটি তৈরি করা হয় না।

3. 

    SELECT   

           Name  
    FROM temp1
    FOR XML PATH('');

    Ouput:
    <Name>aaa</Name>
    <Name>bbb</Name>
    <Name>ccc</Name>
    <Name>ddd</Name>
    <Name>eee</Name>

4. SELECT   
        ',' +Name  
FROM temp1
FOR XML PATH('')

Ouput:
,aaa,bbb,ccc,ddd,eee

চতুর্থ ধাপে আমরা মানগুলি নিয়ে আলোচনা করছি।

5. SELECT ID,
    abc = (SELECT   
            ',' +Name  
    FROM temp1
    FOR XML PATH('') )
FROM temp1

Ouput:
1   ,aaa,bbb,ccc,ddd,eee
1   ,aaa,bbb,ccc,ddd,eee
1   ,aaa,bbb,ccc,ddd,eee
1   ,aaa,bbb,ccc,ddd,eee
1   ,aaa,bbb,ccc,ddd,eee


6. SELECT ID,
    abc = (SELECT   
            ',' +Name  
    FROM temp1
    FOR XML PATH('') )
FROM temp1 GROUP by iD

Ouput:
ID  abc
1   ,aaa,bbb,ccc,ddd,eee

Step ধাপে আমরা তারিখটি আইডি দ্বারা গোষ্ঠীভুক্ত করছি।

STUFF (উত্স_আরক্ষক, শুরু, দৈর্ঘ্য, অ্যাড_স্ট্রিং) পরামিতি বা আর্গুমেন্ট উত্স_ স্ট্রিং সংশোধন করার উত্স স্ট্রিং। দৈর্ঘ্যের অক্ষর মুছতে উত্স_ স্ট্রিংয়ের অবস্থানটি শুরু করুন এবং তারপরে অ্যাড_স্ট্রিং .োকান। দৈর্ঘ্য উত্স_স্ট্রিং থেকে মুছে ফেলার অক্ষরের সংখ্যা। add_string সূচিত অবস্থানের উত্স_ স্ট্রিংয়ের মধ্যে প্রবেশ করানোর জন্য অক্ষরের ক্রম।

SELECT ID,
    abc = 
    STUFF (
        (SELECT   
                ',' +Name  
        FROM temp1
        FOR XML PATH('')), 1, 1, ''
    )
FROM temp1 GROUP by iD

Output:
-----------------------------------
| Id        | Name                |
|---------------------------------|
| 1         | aaa,bbb,ccc,ddd,eee |
-----------------------------------

1
আপনি লিখুন "চতুর্থ ধাপে আমরা মানগুলিকে সম্মতি দিচ্ছি।" তবে এটি কেন পরিষ্কার নয় যে কেন / কীভাবে ','নির্ধারিত কলামটি ('')এক্সএমএল পথের সাথে মিলিত হওয়ার পরে একত্রীকরণ ঘটায়
বার্লপ

পদক্ষেপ 4-এ, কোনও স্ট্রিং অপারেশন করা নির্দিষ্ট ক্ষেত্রে মোড়ানো উপাদান ব্যবহার করবে যা এই ক্ষেত্রে ফাঁকা ('') is
ভিসিলিউশন

1
4 নং পয়েন্ট সম্পর্কে কেন ভাবছেন এবং কেন <নাম> অদৃশ্য হয়ে যায়। এটি কারণ কমা দিয়ে সংক্ষিপ্তকরণ নাম পরে আর কলাম নেই কিন্তু কেবল মূল্য, তাই এসকিউএল সার্ভার জানেন না যে এক্সএমএল ট্যাগের জন্য কোন নামটি ব্যবহার করা উচিত। উদাহরণ হিসেবে বলা যায় এই প্রশ্নের সাথে SELECT 'a' FROM some_table FOR XML PATH('')হবে উত্পাদন: 'aaaaaaa'। তবে যদি কলামের নাম নির্দিষ্ট করা থাকে: SELECT 'a' AS Col FROM some_table FOR XML PATH('')আপনি ফলাফল পাবেন:<Col>a</Col><Col>a</Col><Col>a</Col>
আন্থ

23

এই সঠিক দৃশ্যটি পরিচালনা করতে আজুর এসকিউএল ডেটাবেস এবং এসকিউএল সার্ভারে (২০১ with দিয়ে শুরু) খুব নতুন কার্যকারিতা রয়েছে। আমি বিশ্বাস করি যে আপনি এক্সএমএল / এসটিইউএফ পদ্ধতিটি অর্জনের জন্য যা চেষ্টা করছেন তার জন্য এটি একটি স্থানীয় অফিসিয়াল পদ্ধতি হিসাবে কাজ করবে। উদাহরণ:

select id, STRING_AGG(name, ',') as abc
from temp1
group by id

STRING_AGG - https://msdn.microsoft.com/en-us/library/mt790580.aspx

সম্পাদনা: আমি মূলত এটি পোস্ট করার সময় আমি এসকিউএল সার্ভার 2016 এর উল্লেখ করেছি কারণ আমি ভেবেছিলাম যে আমি দেখেছি যে কোনও সম্ভাব্য বৈশিষ্ট্যটিতে অন্তর্ভুক্ত করা হবে। হয় আমার মনে আছে ভুলভাবে বা কিছু পরিবর্তিত হয়েছে, সংস্করণটি ঠিক করার প্রস্তাবিত সম্পাদনার জন্য ধন্যবাদ। এছাড়াও, বেশ অভিভূত এবং মাল্টি-স্টেপ পর্যালোচনা প্রক্রিয়া সম্পর্কে পুরোপুরি সচেতন ছিল না যা আমাকে চূড়ান্ত বিকল্পের জন্য নিয়ে এসেছিল।


3
STRING_AGG এসকিউএল সার্ভার 2016-এ নেই It এটি "ভিএনেক্সট" এ আসছে বলে জানা গেছে।
N8allan

ওহো, আমি @ লাস্টমাইলগিনের সম্পাদনাটি ওভাররাইট করার অর্থ এই নয় যে এর জন্য দুঃখিত ... এটি হ'ল প্রকৃতপক্ষে সংশোধন সম্পাদনার মাধ্যমে ধাক্কা।
ব্রায়ান জর্ডেন

5

ইন for xml path, আমরা যদি এর মতো কোনও মান সংজ্ঞায়িত করি [ for xml path('ENVLOPE') ]তবে প্রতিটি সারিতে এই ট্যাগগুলি যুক্ত করা হবে:

<ENVLOPE>
</ENVLOPE>

2
SELECT ID, 
    abc = STUFF(
                 (SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
               ) 
FROM temp1 GROUP BY id

এখানে উপরোক্ত ক্যোয়ারিতে STUFF ফাংশনটি প্রথম (,)উত্পাদিত এক্সএমএল স্ট্রিং থেকে প্রথম কমা অপসারণ করতে ব্যবহৃত (,aaa,bbb,ccc,ddd,eee)হবে তা হয়ে যাবে (aaa,bbb,ccc,ddd,eee)

এবং FOR XML PATH('')কেবল কলামের ডেটা (,aaa,bbb,ccc,ddd,eee)স্ট্রিংয়ে কিন্তু PATH তে রূপান্তর করে আমরা '' যাচ্ছি যাতে এটি কোনও এক্সএমএল ট্যাগ তৈরি করে না।

এবং শেষে আমরা আইডি কলাম ব্যবহার করে রেকর্ডগুলি গোষ্ঠীভুক্ত করেছি ।


2

আমি ডিবাগিং করেছি এবং অবশেষে আমার 'স্টাফড' কোয়েরিটি এটি স্বাভাবিক উপায়ে ফিরিয়ে দিয়েছি।

কেবল

select * from myTable for xml path('myTable')

আমার ডিবাগ হওয়া ট্রিগার থেকে লগ টেবিলটিতে লেখার জন্য আমাকে টেবিলের সামগ্রী সরবরাহ করে।


1
Declare @Temp As Table (Id Int,Name Varchar(100))
Insert Into @Temp values(1,'A'),(1,'B'),(1,'C'),(2,'D'),(2,'E'),(3,'F'),(3,'G'),(3,'H'),(4,'I'),(5,'J'),(5,'K')
Select X.ID,
stuff((Select ','+ Z.Name from @Temp Z Where X.Id =Z.Id For XML Path('')),1,1,'')
from @Temp X
Group by X.ID

-1

STUFF ((আলাদা আলাদা নির্বাচন করুন ',' + কাস্ট (টি। আইডি) টি টেবিল টি থেকে যেখানে টিএমআইডি = 1 এক্সএমএল পাঠের জন্য ('')), 1,1, '') নাম হিসাবে


-3

আমি প্রায়শই যেখানে ক্লজ ব্যবহার করছি

SELECT 
TapuAda=STUFF(( 
SELECT ','+TBL.TapuAda FROM (
SELECT TapuAda FROM T_GayrimenkulDetay AS GD 
INNER JOIN dbo.T_AktiviteGayrimenkul AS AG ON  D.GayrimenkulID=AG.GayrimenkulID WHERE 
AG.AktiviteID=262
) AS TBL FOR XML PATH ('')
),1,1,'')

2
আমি দেখতে পাচ্ছি না এটি কীভাবে উত্তর, আপনি কি কিছু ব্যাখ্যা দিয়ে টস করতে পারেন দয়া করে?
গার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.