2017-11-03 70 views
13

मेरे पास SQLServer 2008r2 में नीचे एक तालिका है।एकाधिक मूल्यों के साथ कॉलम द्वारा टीएसक्यूएल समूह

example dataset

मैं सभी रिकॉर्ड का चयन करना चाहते हैं जहां [Fg] स्तंभ = 1 कि लगातार प्रत्येक [T_Id] और [N_Id] संयोजन के लिए मूल्य 2 में [Id] आदेश नेतृत्व द्वारा।

कई ऐसे उदाहरण हैं जहां रिकॉर्ड से पहले [Fg] = 2 करता है हो सकता है नहीं = 1

रिकॉर्ड के किसी भी संख्या में हो सकता है जहां [Fg] = 1 का मान, लेकिन केवल एक रिकॉर्ड जहां [Fg] = 2 प्रत्येक [T_Id] के लिए और [N_Id] संयोजन।

तो नीचे दिए गए उदाहरण के लिए, मैं [Id] एस (4,5) और (7,8, 9) और (1 9, 20) के साथ रिकॉर्ड चुनना चाहता हूं।

[T_Id] 3 और 4 के लिए कोई भी रिकॉर्ड शामिल नहीं है।

अपेक्षित उत्पादन

Expected output

उदाहरण डेटा सेट

DECLARE @Data TABLE (Id INT IDENTITY (1,1), T_Id INT, N_Id INT, Fg TINYINT) 

INSERT INTO @Data 
(T_Id, N_Id, Fg) 
VALUES 
(1, 2, 0), (1, 2, 1), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 3, 0), (2, 3, 1), 
(2, 3, 1), (2, 3, 2), (3, 4, 0), (3, 4, 0), (3, 4, 0), (3, 4, 2), (4, 5, 0), 
(4, 5, 1), (4, 5, 0), (4, 5, 2), (5, 7, 0), (5, 7, 1), (5, 7, 2) 
+0

तो, एफजी 0 के साथ सभी रिकॉर्ड फ़िल्टर किए जाने हैं? क्योंकि अन्यथा 0, 1, 2 रिकॉर्ड्स रिकॉर्ड करने का सही क्रम होगा, नहीं? और ID 7 और 8 दोनों के बाद आईडी 7 को सही रिकॉर्ड के रूप में क्यों अपेक्षित किया गया है, दोनों में एफजी 1 है? – Tyron78

+0

@ Tyron78 ​​आपके पास लगातार कई रिकॉर्ड हो सकते हैं जहां FG = 1. मैंने इसे –

+0

प्रश्न में समझाया है [AL] [https://blogs.msdn.microsoft.com/sqlreleaseservices/end-of-mainstream-support- के लिए-एसक्यूएल सर्वर 2008 और एसक्यूएल सर्वर-2008-r2 /); SQLServer 2008r2 का उपयोग क्यों कर रहे हैं? –

उत्तर

12

यह किया जा सकता है आसानी से recursive CTE का उपयोग कर:

WITH DataSource AS 
(
    SELECT DS1.* 
    FROM @Data DS1 
    INNER JOIN @Data DS2 
     ON DS1.[T_Id] = DS2.[T_Id] 
     AND DS1.[N_Id] = DS2.[N_Id] 
     AND DS1.[Id] = DS2.[Id] + 1 
     AND DS1.[Fg] = 2 
     AND DS2.[Fg] = 1 
    UNION ALL 
    SELECT DS1.* 
    FROM @Data DS1 
    INNER JOIN DataSource DS2 
     ON DS1.[T_Id] = DS2.[T_Id] 
     AND DS1.[N_Id] = DS2.[N_Id] 
     AND DS1.[Id] = DS2.[Id] - 1 
     AND DS1.[Fg] = 1 
) 
SELECT * 
FROM DataSource 
ORDER BY Id 

enter image description here

विचार सरल है। क्वेरी का पहला भाग validfg = 2 के साथ रिकॉर्ड प्राप्त करता है - वैध मतलब है कि उसी समूह से fg = 1 के साथ इस से पहले रिकॉर्ड है।

फिर रिकर्सिव भाग में हमें प्रारंभिक वाले सभी रिकॉर्ड छोटे होते जा रहे हैं, जिनमें fg = 1 है।

+2

यह अद्भुत है। मैं एक लंबे समय के लिए कोशिश कर रहा हूँ। धन्यवाद ... – DineshDB

+2

@gotqn इसके लिए धन्यवाद। मैं 'क्रॉस एप्पल' समाधान के साथ लंबे समय तक गड़बड़ कर रहा था। –

0

आप एसक्यूएल 2012 में शुरू होने के कारण अंतराल/लीड का उपयोग नहीं कर सकते हैं, आपको नीचे की तरह कुछ करने की आवश्यकता होगी।

SELECT fg - (
     SELECT TOP 1 fg 
     FROM table m2 
     WHERE m2.fg = m1.fg-1 OR (m2.fg = m1.fg AND m2.id < m1.id) 
     ORDER BY 
       fg, id 
     ) 
FROM table m1 
ORDER BY 
     fg, id 
संबंधित मुद्दे