जनक-बाल वृक्ष पदानुक्रमित आदेश


21

मुझे SQL Server 2008 R2 में डेटा का पालन करना है। SQLFiddle

स्कीमा:

बनाएँ तालिका [dbo]। [ICFilters] (
   [ICFilterID] [int] पहचान (१११) पूरी नहीं,
   [पेरेंटिड] [इंट] नॉट डिफॉल्ट 0,
   [FilterDesc] [varchar] (50) नहीं, NULL,
   [सक्रिय] [नन्हे मुन्ने] पूरी तरह से पागल नहीं १,
 CONSTRAINT [PK_ICFilters] प्राथमिक कुंजी आवश्यक है 
 ((ICFilterID) ASC) के साथ 
    PAD_INDEX = बंद,
    सांख्यिकी_NORECOMPUTE = OFF,
    IGNORE_DUP_KEY = OFF,
    ALLOW_ROW_LOCKS = ON,
    ALLOW_PAGE_LOCKS = ON
 ) [प्राथमिक]
) [प्राथमिक]

INSERT INTO [dbo]। [ICFilters] (पेरेंटिड, फ़िल्टरडेस, एक्टिव)
मान 
(0, 'उत्पाद प्रकार', 1),
(1, 'ProdSubType_1', 1),
(1, 'ProdSubType_2', 1),
(1, 'ProdSubType_3', 1),
(1, 'ProdSubType_4', 1),
(2, 'PST_1.1', 1),
(2, 'PST_1.2', 1),
(2, 'PST_1.3', 1),
(2, 'PST_1.4', 1),
(2, 'PST_1.5', 1),
(2, 'PST_1.6', 1),
(2, 'PST_1.7', 0),
(3, 'PST_2.1', 1),
(3, 'PST_2.2', 0),
(3, 'PST_2.3', 1),
(3, 'PST_2.4', 1),
(14, 'PST_2.2.1', 1),
(14, 'PST_2.2.2', 1),
(14, 'PST_2.2.3', 1),
(3, 'PST_2.8', 1)

तालिका:

| ICFILTERID | PARENTID | FILTERDESC | सक्रिय |
--------------------------------------------------
| 1 | 0 | उत्पाद प्रकार | 1 |
| 2 | 1 | ProdSubType_1 | 1 |
| 3 | 1 | ProdSubType_2 | 1 |
| 4 | 1 | ProdSubType_3 | 1 |
| 5 | 1 | ProdSubType_4 | 1 |
| 6 | 2 | PST_1.1 | 1 |
| 7 | 2 | PST_1.2 | 1 |
| 8 | 2 | PST_1.3 | 1 |
| 9 | 2 | PST_1.4 | 1 |
| 10 | 2 | PST_1.5 | 1 |
| 11 | 2 | PST_1.6 | 1 |
| 12 | 2 | PST_1.7 | 0 |
| 13 | 3 | PST_2.1 | 1 |
| 14 | 3 | PST_2.2 | 0 |
| 15 | 3 | PST_2.3 | 1 |
| 16 | 3 | PST_2.4 | 1 |
| 17 | 14 | PST_2.2.1 | 1 |
| 18 | 14 | PST_2.2.2 | 1 |
| 19 | 14 | PST_2.2.3 | 1 |
| 20 | 3 | PST_2.8 | 1 |

हर पंक्ति में उसके माता-पिता की आईडी और रूट है parentid = 0FilterDescरों इसलिए मैं आदेश देने के लिए उन पार्स करने के लिए कोशिश नहीं कर सकते सिर्फ नमूना बताया गया है।

प्रश्न

क्या पेड़ की तरह सभी पंक्तियों का चयन करना संभव है? यदि हां, तो कैसे? जब मैं 'ट्री-लाइक' कहता हूं, तो मेरा मतलब है कि उसके सभी बच्चों के माता-पिता का पुनरावर्ती चयन करें, फिर उन सभी में से प्रत्येक के सभी बच्चे और इसी तरह। एक गहराई का पहला पेड़ ट्रैवर्सल।

मेरे दोस्तों और मैंने कोशिश की है, लेकिन हम काम करने के समाधान से कम हो गए हैं, लेकिन कोशिश करते रहेंगे। मैं sql में काफी नया हूँ इसलिए शायद यह आसानी से किया जा सकता है और मैं बस चीजों को आवश्यकता से अधिक कठिन बना रहा हूं।

उदाहरण (वांछित) आउटपुट:

| ICFILTERID | PARENTID | FILTERDESC | सक्रिय |
--------------------------------------------------
| 1 | 0 | उत्पाद प्रकार | 1 |
| 2 | 1 | ProdSubType_1 | 1 |
| 6 | 2 | PST_1.1 | 1 |
| 7 | 2 | PST_1.2 | 1 |
| 8 | 2 | PST_1.3 | 1 |
| 9 | 2 | PST_1.4 | 1 |
| 10 | 2 | PST_1.5 | 1 |
| 11 | 2 | PST_1.6 | 1 |
| 12 | 2 | PST_1.7 | 0 |
| 3 | 1 | ProdSubType_2 | 1 |
| 13 | 3 | PST_2.1 | 1 |
| 14 | 3 | PST_2.2 | 0 |
| 17 | 14 | PST_2.2.1 | 1 |
| 18 | 14 | PST_2.2.2 | 1 |
| 19 | 14 | PST_2.2.3 | 1 |
| 15 | 3 | PST_2.3 | 1 |
| 16 | 3 | PST_2.4 | 1 |
| 20 | 3 | PST_2.8 | 1 |
| 4 | 1 | ProdSubType_3 | 1 |
| 5 | 1 | ProdSubType_4 | 1 |

सीटीई का उपयोग करना सबसे अच्छा होगा
परिजन शाह

1
यहां एक थ्रेड को टेबल डेटा के बिना वांछित परिणाम दिखाते हुए दिखाया गया है, जिसे किसी विशेष क्रम में लोड किया जाना है। यह "पथ" बनाने के लिए row_number () और विभाजन का उपयोग करता है जो वांछित छंटाई को सक्षम करता है। Ask.sqlservercentral.com/questions/48518/…

जवाबों:


25

ठीक है, पर्याप्त मस्तिष्क कोशिकाएं मृत हैं।

एसक्यूएल फिडल

WITH cte AS
(
  SELECT 
    [ICFilterID], 
    [ParentID],
    [FilterDesc],
    [Active],
    CAST(0 AS varbinary(max)) AS Level
  FROM [dbo].[ICFilters]
  WHERE [ParentID] = 0
  UNION ALL
  SELECT 
    i.[ICFilterID], 
    i.[ParentID],
    i.[FilterDesc],
    i.[Active],  
    Level + CAST(i.[ICFilterID] AS varbinary(max)) AS Level
  FROM [dbo].[ICFilters] i
  INNER JOIN cte c
    ON c.[ICFilterID] = i.[ParentID]
)

SELECT 
  [ICFilterID], 
  [ParentID],
  [FilterDesc],
  [Active]
FROM cte
ORDER BY [Level];

2
मुझे ठीक इसी की आवश्यकता थी! मैं सहमत हूं कि इस पर कई मस्तिष्क कोशिकाओं की मृत्यु हो गई है। क्या मैं स्पष्ट नहीं था कि मैं क्या चाहता हूं? यदि ऐसा है तो मैं भविष्य के संदर्भ के लिए प्रश्न को संपादित करूंगा। मैं निश्चित रूप से इसे कठिन होने की तुलना में कठिन बना रहा था ...
अर्चंगेल

1
@ Archangel33 आपने एक अच्छा काम किया और इस मुद्दे को सुलझाया। इसके अलावा, sqlfiddle वास्तव में मदद करते हैं।
ट्रैविस

2
+1 लेकिन [ICFilterID] का उपयोग करते हुए [int] पहचान करने के लिए पहचान (1,1) केवल काम करेगा यह आइटम सही अनुक्रम में डाले गए हैं, लेकिन सॉर्टिंग के लिए एक अन्य क्षेत्र अभी भी OT
bummi

4
मैं नहीं मानता कि यह 100% सही समाधान है। अल कठिन यह पदानुक्रम में अपने सही स्तर के साथ सभी पंक्तियों को सूचीबद्ध करता है, यह इसे उस क्रम में सूचीबद्ध नहीं करता है जिसमें सवाल उनसे पूछा जाता है। क्या प्रश्न के अनुसार सही क्रम में पंक्तियों को सूचीबद्ध करना संभव होगा? यही मैं भी ढूंढ रहा हूं।

1
यह मेरे प्रश्न का उत्तर देता है क्योंकि [FilterDesc]कॉलम में दिए गए डेटा काल्पनिक हैं और यह आदेश अनावश्यक / महत्वहीन है। @Travis Gan के जवाब में तर्क के बाद सभी को यह करने के लिए एक और आदेश जोड़ना CASTहोगा Level। जैसे। Level + CAST( CAST(i.[ICFilterID] AS varbinary(max)) AS Levelबन जाता है Level + CAST(i.[FilterDesc] AS varbinary(max)) + CAST(i.[ICFilterID] AS varbinary(max)) AS Level
Archangel33

1

उपरोक्त मेरे लिए सही ढंग से काम नहीं करता है। फेसबुक प्रकार के डेटा के साथ 2 टेबल सेटअप की कल्पना करें। तालिका 1, में PostId + है जो आप अन्य क्षेत्रों में हैं। PostId स्वतः वृद्धि है और स्पष्ट रूप से आपके इंटरफ़ेस में, आप सबसे ऊपर नवीनतम पोस्ट करने के लिए DESC को सॉर्ट करेंगे।

अब टिप्पणी तालिका के लिए। तालिका 2 यह तालिका CommentId प्राथमिक कुंजी, ऑटो नंबर है। अपने gui में, आप इसे ASC प्रदर्शित करना चाहते हैं, ताकि थ्रेड को पढ़ते समय, यह समझ में आए। (सबसे पुरानी (छोटी संख्या) शीर्ष पर) तालिका 2 में अन्य महत्वपूर्ण कुंजी हैं: PostId (FK वापस पदों पर), और ParentId (FK to CommentId) जहां ParentId NULL होगा यदि यह "मूल" पोस्ट पर टिप्पणी है। यदि कोई व्यक्ति किसी टिप्पणी पर प्रतिक्रिया देता है, तो पैरेंटआईड टिप्पणी के साथ आबाद हो जाएगा।
आशा है कि आप लोगों को बहाव मिलेगा। सीटीई इस तरह दिखेगा:

WITH  Comments
        AS ( SELECT  CommentId , ParentId, CAST(CommentId AS VARBINARY(MAX)) AS Sortkey, 0 AS Indent
             FROM    dbo.Comments
             WHERE   ParentId IS NULL AND PostId = 105
             UNION ALL
             SELECT  b.CommentId , b.ParentId,  c.Sortkey + CAST(b.CommentId AS varbinary(max))  AS Sortkey, c.Indent + 1 AS Indent
             FROM    dbo.Comments b
             INNER JOIN Comments c ON c.CommentId = b.ParentId
           )
   SELECT   *
   FROM     Comments
   ORDER BY Sortkey

नमूना उत्पादन

1   NULL    0x0000000000000001  0
5   1   0x00000000000000010000000000000001  1
6   5   0x000000000000000100000000000000010000000000000005  2
2   NULL    0x0000000000000002  0

F / B पोस्ट 105 पर, एक टिप्पणी दो थी (टिप्पणी 1 और 2) किसी ने तब टिप्पणी 1 पर टिप्पणी की (टिप्पणी 5, अभिभावक 1), और फिर किसी और ने उस उत्तर पर टिप्पणी की, इसलिए टिप्पणी 5 (टिप्पणी 6, अभिभावक 6) पर

और वायोला, अनुक्रम सही है, पोस्ट के तहत, अब आप टिप्पणियों को सही अनुक्रम में दिखा सकते हैं। पदों को इंडेंट करने के लिए ताकि यह फ़ेसबुक की तरह बने और रूपरेखा तैयार हो (जितना गहरा स्तर जाता है, उतना ही इसे बाईं ओर से मार्जिन किया जाना चाहिए), मेरे पास एक कॉलम भी है जिसे Indent कहा जाता है। जड़ें 0 हैं और फिर संघ में, हमारे पास c.ndent + 1 AS Indent कोड में, yo अब इंडेंट को 32px मानने के साथ गुणा कर सकता है, और टिप्पणियों को एक अच्छी पदानुक्रम और रूपरेखा में दिखा सकता है।

मुझे ऑटो इंक्रीमेंट की प्राथमिक कुंजी का उपयोग करने में कोई समस्या नहीं दिखती है


0
create table pc ( parent varchar(10), child varchar(10) )

insert into pc values('a','b');
insert into pc values('a','c');
insert into pc values('b','e');
insert into pc values('b','f');
insert into pc values('a','d');
Insert into pc values('b','g');
insert into pc values('c','h');
insert into pc values('c','i');
insert into pc values('d','j');
insert into pc values('f','k');
insert into pc values('x','y');
insert into pc values('y','z');
insert into pc values('m','n');

 DECLARE @parent varchar(10) = 'a';
 WITH cte AS
 (
  select null parent, @parent child, 0 as level
   union
  SELECT  a.parent, a.child , 1 as level
    FROM pc a
   WHERE a.parent = @parent
   UNION ALL
  SELECT a.parent, a.child , c.level +    1
  FROM pc a JOIN cte c ON a.parent = c.child
  )
  SELECT distinct parent, child , level
  FROM cte
  order by level, parent

यह आपको सभी वंशज और स्तर देगा।
उम्मीद है की यह मदद करेगा :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.