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

समूहीकृत मूल्यों या वस्तु की पहचान करने के लिए देखें

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

नोट:स्पष्टता के लिए लाइन ब्रेक जोड़े गए हैं। संपूर्ण ब्लॉक एक ही प्रश्न है

;with Walker(StartX,StartY,X,Y,Visited) as (
    select X,Y,X,Y,CAST('('+right(X,3)+','+right(Y,3)+')' as Varchar(Max))
    from puzzle
    union all
    select W.StartX,W.StartY,P.X,P.Y,W.Visited+'('+right(P.X,3)+','+right(P.Y,3)+')'
    from Walker W
    join Puzzle P on
      (W.X=P.X   and W.Y=P.Y+1 OR   -- these four lines "collect" a cell next to
       W.X=P.X   and W.Y=P.Y-1 OR   -- the current one in any direction
       W.X=P.X+1 and W.Y=P.Y   OR
       W.X=P.X-1 and W.Y=P.Y)
      AND W.Visited NOT LIKE '%('+right(P.X,3)+','+right(P.Y,3)+')%'
)
select X, Y, Visited
from
(
    select W.X, W.Y, W.Visited, rn=row_number() over (
                                   partition by W.X,W.Y
                                   order by len(W.Visited) desc)
    from Walker W
    left join Walker Other
        on Other.StartX=W.StartX and Other.StartY=W.StartY
            and (Other.Y<W.Y or (Other.Y=W.Y and Other.X<W.X))
    where Other.X is null
) Z
where rn=1

पहला कदम एक "वॉकर" रिकर्सिव टेबल एक्सप्रेशन स्थापित करना है जो हर सेल से शुरू होगा और बिना किसी कदम को पीछे हटाए जितना हो सके यात्रा करेगा। यह सुनिश्चित करना कि कक्षों का पुनरीक्षण नहीं किया जाता है, विज़िट किए गए कॉलम का उपयोग करके किया जाता है, जो प्रत्येक प्रारंभिक बिंदु से देखे गए प्रत्येक कक्ष को संग्रहीत करता है। विशेष रूप से, यह स्थिति AND W.Visited NOT LIKE '%('+right(P.X,3)+','+right(P.Y,3)+')%' उन कक्षों को अस्वीकार करता है जिन्हें वह पहले ही देख चुका है।

यह समझने के लिए कि बाकी कैसे काम करता है, आपको सीटीई के बाद "वाकर" सीटीई द्वारा "स्टार्टएक्स, स्टार्टवाई द्वारा वॉकर ऑर्डर से चयन करें" चलाकर उत्पन्न परिणाम को देखना होगा। 5 कोशिकाओं वाला एक "टुकड़ा" कम से कम 5 समूहों में दिखाई देता है, प्रत्येक एक अलग (StartX,StartY) के साथ , लेकिन प्रत्येक समूह में सभी 5 (X,Y) . हैं अलग-अलग "विज़िट" पथ वाले टुकड़े।

सबक्वेरी (Z) स्थिति द्वारा परिभाषित "प्रथम XY निर्देशांक" वाले प्रत्येक समूह में एकल पंक्ति तक समूहों को कम करने के लिए LEFT JOIN + IS NULL का उपयोग करता है

     Other.StartX=W.StartX and Other.StartY=W.StartY
        and (Other.Y<W.Y or (Other.Y=W.Y and Other.X<W.X))

इरादा प्रत्येक सेल के लिए है जिसे (स्टार्टएक्स, स्टार्टवाई) से शुरू किया जा सकता है, एक ही समूह में एक दूसरे सेल के खिलाफ तुलना करने के लिए, और उस सेल को खोजने के लिए जहां कोई अन्य सेल उच्च पंक्ति पर नहीं है, या यदि वे पर हैं वही पंक्ति, इस सेल के बाईं ओर है। हालाँकि, यह अभी भी हमें बहुत अधिक परिणाम देता है। (3,4) और (4,4):

. पर केवल 2-सेल टुकड़े पर विचार करें
StartX  StartY  X   Y   Visited
3       4       3   4   (3,4)          ******
3       4       4   4   (3,4)(4,4)
4       4       4   4   (4,4)
4       4       3   4   (4,4)(3,4)     ******

2 पंक्तियाँ "पहले XY निर्देशांक" (3,4) के साथ रहती हैं, जो ****** . से चिह्नित होती हैं . हमें केवल एक पंक्ति की आवश्यकता है, इसलिए हम Row_Number का उपयोग करते हैं और चूंकि हम क्रमांकन कर रहे हैं, इसलिए हम सबसे लंबे समय तक Visited के लिए भी जा सकते हैं पथ, जो हमें जितना देगा टुकड़े के भीतर की कोशिकाओं को हम प्राप्त कर सकते हैं।

अंतिम बाहरी क्वेरी बस प्रत्येक समान (X,Y) समूह से पहली पंक्तियाँ (RN=1) लेती है।

प्रत्येक टुकड़े के सभी सेल दिखाने के लिए, लाइन बदलें
select X, Y, Visited

बीच में

select X, Y, (
    select distinct '('+right(StartX,3)+','+right(StartY,3)+')'
    from Walker
    where X=Z.X and Y=Z.Y
    for xml path('')
    ) PieceCells

जो यह आउटपुट देते हैं

X           Y           PieceCells
1           1           (1,1)(2,1)(2,2)(3,2)
3           4           (3,4)(4,4)
5           6           (5,6)
7           5           (7,5)(8,5)(9,5)
8           1           (10,1)(8,1)(8,2)(9,1)(9,2)(9,3)


  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. चर के साथ एसक्यूएल उपयोग कथन

  3. एक अस्थायी तालिका में कैसे सम्मिलित करें, जो कि RESTORE FILELISTONLY / HEADERONLY / VERIFYONLY द्वारा दी गई जानकारी है

  4. एसक्यूएल में डिवाइड बाय जीरो एरर को रोकने का आसान तरीका

  5. SQL सर्वर में किसी चीज़ का नाम कैसे बदलें, जिसके नाम पर वर्गाकार कोष्ठक हैं?