Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर तालिका परिणाम SQL Server 2005 में सरणी के लिए है

आप वास्तव में यह सब एक सीटीई चयन क्वेरी में कर सकते हैं, बिना किसी फ़ंक्शन का उपयोग किए। यहां बताया गया है:

सबसे पहले, इस पैरेंट/चाइल्ड टेबल स्ट्रक्चर पर विचार करें:

CREATE TABLE P (ID INT PRIMARY KEY, Description VARCHAR(20));
CREATE TABLE C (ID INT PRIMARY KEY, PID INT, 
                Description VARCHAR(20), 
                CONSTRAINT fk FOREIGN KEY (PID) REFERENCES P(ID));

(मैंने टाइपिंग को बचाने के लिए P और C का उपयोग किया है!)

और कुछ परीक्षण डेटा जोड़ने देता है, जो प्रश्न पूछने वाले से मेल खाता है:

INSERT INTO P VALUES (36, 'Blah Blah');
INSERT INTO P VALUES (20, 'Pah Pah');

INSERT INTO C VALUES (1, 36, 'Bob');
INSERT INTO C VALUES (2, 36, 'Gary');
INSERT INTO C VALUES (3, 36, 'Reginald');
INSERT INTO C VALUES (4, 20, 'Emily');
INSERT INTO C VALUES (5, 20, 'Dave');

फिर अंत में, सीटीई एक्सप्रेशन:

WITH
FirstItems (PID, FirstCID) AS (    

    SELECT C.PID, MIN(C.ID)
      FROM C
     GROUP BY C.PID      
),  
SubItemList (PID, CID, ItemNum) AS (

    SELECT C.PID, C.ID, 1
      FROM C JOIN FirstItems FI ON (C.ID = FI.FirstCID)
    UNION ALL
    SELECT C.PID, C.ID, IL.ItemNum + 1
      FROM C JOIN SubItemList IL ON C.PID = IL.PID AND C.ID > CID
),
ItemList (PID, CID, ItemNum) AS (

    SELECT PID, CID, MAX(ItemNum)
      FROM SubItemList
     GROUP BY PID, CID
),
SubArrayList (PID, CID, Array, ItemNum) AS (

    SELECT IL.PID, IL.CID, CAST(C.Description AS VARCHAR(MAX)), IL.ItemNum
      FROM ItemList IL JOIN C ON IL.CID = C.ID
     WHERE IL.ItemNum = 1
    UNION ALL
    SELECT IL.PID, IL.CID, AL.Array + ',' + CAST(C.Description AS VARCHAR(MAX)), IL.ItemNum
      FROM ItemList IL
      JOIN SubArrayList AL ON (IL.PID = AL.PID AND IL.ItemNum = AL.ItemNum + 1)
      JOIN C ON (IL.CID = C.ID)
),
MaxItems (PID, MaxItem) AS (

    SELECT PID, MAX(ItemNum)
      FROM SubItemList
     GROUP BY PID

),
ArrayList (PID, List) AS (

    SELECT SAL.PID, SAL.Array
      FROM SubArrayList SAL 
      JOIN MaxItems MI ON (SAL.PID = MI.PID AND SAL.ItemNum = MI.MaxItem)

)
SELECT P.ID, P.Description, AL.List
  FROM ArrayList AL JOIN P ON P.ID = AL.PID
 ORDER BY P.ID

परिणाम:

ID Description    List
-- -------------- --------
20 Pah Pah        Emily,Dave
36 Blah Blah      Bob,Gary,Reginald   

यहाँ क्या हो रहा है, यह समझाने के लिए, मैं CTE के प्रत्येक भाग और यह क्या करता है, इसका वर्णन करूँगा।

पहले आइटम सभी बच्चों को देखता है, और अगले पुनरावर्ती चयन के लिए एंकर के रूप में उपयोग करने के लिए प्रत्येक अभिभावक समूह में सबसे कम आईडी ढूंढता है:

FirstItems (PID, FirstCID) AS (
    SELECT C.PID, MIN(C.ID)
      FROM C
     GROUP BY C.PID  
)

उपआइटम सूची एक पुनरावर्ती चयन है जो पिछली क्वेरी से सबसे कम बच्चे को उठाता है, और 1 से शुरू होने वाले प्रत्येक बच्चे को एक वृद्धिशील आइटम नंबर आवंटित करता है:

SubItemList (PID, CID, ItemNum) AS (    
    SELECT C.PID, C.ID, 1
      FROM C JOIN FirstItems FI ON (C.ID = FI.FirstCID)
    UNION ALL
    SELECT C.PID, C.ID, IL.ItemNum + 1
      FROM C JOIN SubItemList IL ON C.PID = IL.PID AND C.ID > CID
)

समस्या यह है कि यह बहुत सारी वस्तुओं को डुप्लिकेट और दोहराता है, इसलिए आइटमसूची प्रत्येक समूह से केवल अधिकतम चुनने के लिए इसे फ़िल्टर करें:

ItemList (PID, CID, ItemNum) AS (
SELECT PID, CID, MAX(ItemNum)
  FROM SubItemList
 GROUP BY PID, CID
)

अब हमारे पास माता-पिता की एक आईडी सूची है जिसमें प्रत्येक बच्चे की संख्या 1 से x तक है:

PID         CID         ItemNum
----------- ----------- -----------
36          1           1
36          2           2
36          3           3
20          4           1
20          5           2

SubArrayList बच्चों की पंक्तियों को लेता है, संख्याओं की सूची में बार-बार जुड़ता है और एक ही विवरण से शुरू करते हुए सभी विवरणों को एक-दूसरे से जोड़ना शुरू करता है:

SubArrayList (PID, CID, Array, ItemNum) AS (    
    SELECT IL.PID, IL.CID, CAST(C.Description AS VARCHAR(MAX)), IL.ItemNum
      FROM ItemList IL JOIN C ON IL.CID = C.ID
     WHERE IL.ItemNum = 1
    UNION ALL
    SELECT IL.PID, IL.CID, AL.Array + ',' + CAST(C.Description AS VARCHAR(MAX)), IL.ItemNum
      FROM ItemList IL
      JOIN SubArrayList AL ON (IL.PID = AL.PID AND IL.ItemNum = AL.ItemNum + 1)
      JOIN C ON (IL.CID = C.ID)
)

परिणाम अब है:

PID         CID         Array             ItemNum
----------- ----------- ----------------- -----------
36          1           Bob               1
20          4           Emily             1
20          5           Emily,Dave        2
36          2           Bob,Gary          2
36          3           Bob,Gary,Reginald 3

तो हमें बस इतना करना है कि सभी आंशिक रूप से संयोजित पंक्तियों से छुटकारा पाएं।

अधिकतम आइटम बस माता-पिता और उनके उच्चतम आइटम नंबरों की एक सूची पकड़ लेता है, जो निम्न क्वेरी को थोड़ा आसान बनाता है:

MaxItems (PID, MaxItem) AS (    
    SELECT PID, MAX(ItemNum)
      FROM SubItemList
     GROUP BY PID        
)

ArrayList पिछली क्वेरी से प्राप्त अधिकतम आइटम संख्या का उपयोग करके आंशिक रूप से संयोजित पंक्तियों का अंतिम चयन करता है:

ArrayList (PID, List) AS (
SELECT SAL.PID, SAL.Array
  FROM SubArrayList SAL 
  JOIN MaxItems MI ON (SAL.PID = MI.PID AND SAL.ItemNum = MI.MaxItem)     
)

और अंत में, जो कुछ बचा है, वह परिणाम को क्वेरी करना है:

SELECT P.ID, P.Description, AL.List
  FROM ArrayList AL JOIN P ON P.ID = AL.PID
 ORDER BY P.ID


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. महीने के नाम को वर्चर में बदलें ताकि महीने के हिसाब से ऑर्डर किया जा सके

  2. SQL में एक पार्टीशन फंक्शन बनाएँ

  3. SQL सर्वर 2000:संयोजन एकत्रीकरण सबक्वेरी करने के लिए विचार

  4. शीर्ष X संपादित करने के लिए मान कैसे बदलें और SQL सर्वर प्रबंधन स्टूडियो (SSMS) में शीर्ष X पंक्तियों का चयन करें - SQL सर्वर / TSQL ट्यूटोरियल भाग 20

  5. हाइबरनेट के माध्यम से एमएस एसक्यूएल से जुड़ना