केवल सुपरसेट चुनें


10

मेरे पास दो टेबल हैं (एक गैर-अनुक्रमित सूचकांक के साथ) जो नीचे दिए गए आदेशों के साथ बनाई जा सकती हैं:

CREATE TABLE GroupTable
(
  GroupKey int NOT NULL PRIMARY KEY, 
  RecordCount int NOT NULL,
  GroupScore float NOT NULL
);

CREATE TABLE RecordTable
(
  RecordKey varchar(10) NOT NULL, 
  GroupKey int NOT NULL,
  PRIMARY KEY(RecordKey, GroupKey)
);

CREATE UNIQUE INDEX ixGroupRecord ON RecordTable(GroupKey, RecordKey);

जबकि तकनीकी रूप से मेरी टेबल कुछ अलग है और मैं कुछ अन्य टेबलों में शामिल हो रहा हूं, यह मेरी स्थिति के लिए उपयुक्त प्रॉक्सी है।

  • मैं उन सभी का चयन करना चाहूंगा GroupKeysजो दूसरे के सबसेट नहीं हैं GroupKey
  • किसी दिए गए सुपरसेट के लिए, मैं GroupScoreइसके सभी सबसेट (स्वयं सहित) को अधिकतम हथियाना चाहूंगा ।
  • उदाहरण में जब किसी अन्य GroupKeyके समान सटीक होता है , तो उनमें से केवल एक को पकड़ा जाता है (यह कोई फर्क नहीं पड़ता कि कौन सा)।RecordKeysGroupKey(s)GroupKeys
  • किसी भी दूसरे GroupKeyके समान ही सटीक भी होगा ।RecordKeysGroupKey(s)GroupScore
  • गैर-संबंधित के GroupKeysपास भी समान स्कोर हो सकता है।

निम्नलिखित उदाहरण है कि मैं क्या पूछ रहा हूं:

              GroupTable                          RecordTable

GroupKey    RecordCount   GroupScore         RecordKey    GroupKey
------------------------------------         ---------------------
  1              3            6.2                A          1
  29             2            9.8                A          29
  95             3            6.2                A          95
  192            4            7.1                A          192
                                                 B          1
                                                 B          29
                                                 B          95
                                                 B          192
                                                 C          1
                                                 C          95
                                                 D          192
                                                 E          192

मैं आउटपुट को निम्न करना चाहूंगा:

GroupKey    RecordCount    GroupScore
-------------------------------------
  1              3             9.8
  192            4             9.8

GroupTableRecordTableलगभग 75M पंक्तियाँ हैं , और लगभग 115M पंक्तियाँ हैं; हालाँकि, जुड़ने और WHEREभविष्यवाणी करने के बाद , एक निश्चित दिन में लगभग 20k पंक्तियाँ हो जाती हैं।

अगर यह सवाल तुच्छ है, तो मैं माफी चाहता हूं, लेकिन किसी कारण से मैं वास्तव में इसके साथ संघर्ष कर रहा हूं।

जवाबों:


7

मैं आउटपुट को निम्न करना चाहूंगा:

 GroupKey    RecordCount    GroupScore
 -------------------------------------
   1              3             9.8
   192            4             7.1

सहसंबद्ध उपश्रेणियों का उपयोग करना अपने इच्छित उत्पादन को प्राप्त करने का एक तरीका है।

  • उदाहरण में जब एक GroupKey में एक और GroupKey (s) के समान RecordKeys होते हैं, तो केवल उन GroupKeys में से एक को पकड़ा जाता है (यह कोई फर्क नहीं पड़ता कि कौन सा)।

जब मैं एक मैच होता है तो मैं सबसे कम GroupKey के साथ समूह को वापस कर रहा हूं, लेकिन जैसा कि आप कहते हैं कि यह कोई फर्क नहीं पड़ता है।

परीक्षण डेटा:

INSERT INTO RecordTable(RecordKey,GroupKey)
VALUES ('A',1)
     , ('A',29)
     , ('A',95)
     , ('A',192)
     , ('B',1)
     , ('B',29)
     , ('B',95)
     , ('B',192)
     , ('C',1)
     , ('C',95)
     , ('D',192)
     , ('E',192);

INSERT INTO GroupTable(GroupKey,RecordCount,GroupScore)
VALUES (1,3,6.2)     -- ABC
     , (29,2,9.8)    -- AB
     , (95,3,6.2)    -- ABC
     , (192,4,7.1);  -- ABDE
GO

क्वेरी:

SELECT GroupKey
     , RecordCount
     , GroupScore = ( SELECT max(GroupScore)
                      FROM GroupTable g2 
                      WHERE ( SELECT count(*)
                              FROM ( SELECT RecordKey
                                     FROM RecordTable
                                     WHERE GroupKey=g1.GroupKey
                                     UNION
                                     SELECT RecordKey
                                     FROM RecordTable
                                     WHERE GroupKey=g2.GroupKey ) z
                            )=g1.RecordCount )
FROM GroupTable g1
WHERE NOT EXISTS ( SELECT *
                   FROM GroupTable g3
                   WHERE ( SELECT count(*)
                           FROM ( SELECT RecordKey
                                  FROM RecordTable 
                                  WHERE GroupKey=g1.GroupKey 
                                  UNION
                                  SELECT RecordKey 
                                  FROM RecordTable 
                                  WHERE GroupKey=g3.GroupKey ) z )=g3.RecordCount
                         AND ( g3.RecordCount>g1.RecordCount 
                               OR ( g3.RecordCount=g1.RecordCount 
                                    AND g3.GroupKey<g1.GroupKey ) ) );
GO

SELECT में उपश्रेणी GroupScoreकेवल उन्हीं समूहों से प्राप्त होती है जो इस ('g1') समूह के सबसेट हैं। यह RecordKey'g1' सेट और प्रत्येक 'g2' सेट के UNION को गिनकर इसे प्राप्त करता है । यदि UNION 'g1' सेट से बड़ा है, तो RecordKey'g2' सेट के RecordKeyलिए संबंधित 'g2' सेट में कम से कम एक होना चाहिए , इसलिए 'g2' सेट एक उपसमूह नहीं है और इसके लिए विचार नहीं किया जाना चाहिए यह पंक्ति।

WHERE क्लॉज में, फ़िल्टरिंग के लिए विचार करने के लिए दो मामले हैं। या तो मामले में, 'g1' सेट केवल तभी फ़िल्टर किया जाता है यदि सभी 'g1 RecordKey' सेट 'g3' सेट में भी मौजूद हों; और यह चेक यूनियन को फिर से (सेलेक्ट क्लॉज के अनुसार) गिनकर हासिल किया जाता है।

दो मामले हैं: 1 'जी 1' सेट में कम RecordKeyएस ( g3.RecordCount>g1.RecordCount; जिस स्थिति में हम फ़िल्टर करते हैं), और 'जी 1' सेट 'जी 3' सेट के समान है ( g3.RecordCount=g1.RecordCountजिस स्थिति में हम मनमाने ढंग से सेट का चयन करते हैं; कम GroupKey)

उत्पादन:

/*
|GroupKey|RecordCount|GroupScore|
|-------:|----------:|---------:|
|       1|          3|       9.8|
|     192|          4|       9.8|
*/

यहाँ dbfiddle


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