PARTITION BY
अलग सेट, यह आपको स्वतंत्र रूप से संबंधित सेट पर (ROW_NUMBER(),COUNT(),SUM(),etc) काम करने में सक्षम बनाता है।
आपकी क्वेरी में, संबंधित सेट में समान cdt.country_code, cdt.account, cdt.currency वाली पंक्तियाँ शामिल थीं। जब आप उन स्तंभों पर विभाजन करते हैं और आप उन पर ROW_NUMBER लागू करते हैं। उन संयोजन/सेट के अन्य कॉलमों को ROW_NUMBER से क्रमिक संख्या प्राप्त होगी
लेकिन वह प्रश्न मजाकिया है, यदि आपका विभाजन कुछ अद्वितीय डेटा द्वारा किया जाता है और आप उस पर row_number डालते हैं, तो यह वही संख्या उत्पन्न करेगा। यह ऐसा है जैसे आप एक विभाजन पर एक ORDER BY करते हैं जो अद्वितीय होने की गारंटी है। उदाहरण के लिए, GUID को cdt.country_code, cdt.account, cdt.currency
के अद्वितीय संयोजन के रूप में सोचें
newid()
GUID उत्पन्न करता है, तो आप इस व्यंजक से क्या अपेक्षा करेंगे?
select
hi,ho,
row_number() over(partition by newid() order by hi,ho)
from tbl;
... ठीक है, सभी विभाजित (कोई भी विभाजित नहीं किया गया था, प्रत्येक पंक्ति को अपनी पंक्ति में विभाजित किया गया है) पंक्तियों की पंक्ति_संख्या सभी 1 पर सेट हैं
मूल रूप से, आपको गैर-अद्वितीय स्तंभों पर विभाजन करना चाहिए। ORDER BY OVER को एक गैर-अद्वितीय संयोजन के लिए PARTITION BY की आवश्यकता थी, अन्यथा सभी row_numbers 1 हो जाएंगे
एक उदाहरण, यह आपका डेटा है:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','X'),
('A','Y'),
('A','Z'),
('B','W'),
('B','W'),
('C','L'),
('C','L');
फिर यह आपकी क्वेरी के समान है:
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho)
from tbl;
इसका आउटपुट क्या होगा?
HI HO COLUMN_2
A X 1
A Y 1
A Z 1
B W 1
B W 2
C L 1
C L 2
आप आपको HI HO का संयोजन देखते हैं? पहली तीन पंक्तियों में अद्वितीय संयोजन है, इसलिए वे 1 पर सेट हैं, बी पंक्तियों में एक ही डब्ल्यू है, इसलिए अलग-अलग ROW_NUMBERS, इसी तरह HI C पंक्तियों के साथ।
अब, ORDER BY
क्यों है वहाँ की जरूरत है? यदि पिछला डेवलपर समान डेटा पर केवल row_number डालना चाहता है (उदा. HI B, सभी डेटा B-W, B-W हैं), तो वह बस ऐसा कर सकता है:
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
लेकिन अफसोस, Oracle (और Sql सर्वर भी) बिना ORDER BY
के विभाजन की अनुमति नहीं देता है; जबकि Postgresql में, ORDER BY
विभाजन पर वैकल्पिक है:http://www.sqlfiddle.com/#!1/27821/1
select
hi,ho,
row_number() over(partition by hi,ho)
from tbl;
आपका ORDER BY
आपके विभाजन पर थोड़ा बेमानी लग रहा है, पिछले डेवलपर की गलती के कारण नहीं, कुछ डेटाबेस बस PARTITION
की अनुमति नहीं देते हैं बिना ORDER BY
. के , हो सकता है कि उन्हें छांटने के लिए एक अच्छा उम्मीदवार कॉलम न मिले। यदि कॉलम द्वारा पार्टिशन और कॉलम द्वारा ऑर्डर दोनों समान हैं, तो बस ऑर्डर को हटा दें, लेकिन चूंकि कुछ डेटाबेस इसकी अनुमति नहीं देते हैं, इसलिए आप बस यह कर सकते हैं:
SELECT cdt.*,
ROW_NUMBER ()
OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency
ORDER BY newid())
seq_no
FROM CUSTOMER_DETAILS cdt
आपको समान डेटा को सॉर्ट करने के लिए उपयोग करने के लिए एक अच्छा कॉलम नहीं मिल रहा है? आप यादृच्छिक रूप से भी छाँट सकते हैं, विभाजित डेटा में समान मान . होते हैं फिर भी। उदाहरण के लिए आप GUID का उपयोग कर सकते हैं (आप newid()
. का उपयोग करते हैं SQL सर्वर के लिए)। इसलिए पिछले डेवलपर द्वारा समान आउटपुट दिया गया है, यह दुर्भाग्यपूर्ण है कि कुछ डेटाबेस PARTITION
की अनुमति नहीं देते हैं बिना ORDER BY
. के
हालांकि वास्तव में, यह मुझे दूर करता है और मुझे एक ही संयोजन पर एक संख्या डालने का एक अच्छा कारण नहीं मिल रहा है (बी-डब्ल्यू, बी-डब्ल्यू ऊपर उदाहरण में)। यह अनावश्यक डेटा वाले डेटाबेस का आभास दे रहा है। किसी तरह मुझे यह याद दिलाया:तालिका से रिकॉर्ड की एक ही सूची से एक अनूठा रिकॉर्ड कैसे प्राप्त करें? तालिका में कोई अद्वितीय बाधा नहीं है
ORDER BY के साथ स्तंभों के समान संयोजन के साथ PARTITION BY को देखकर यह वास्तव में रहस्यमय लगता है, आसानी से कोड के इरादे का अनुमान नहीं लगा सकता है।
लाइव परीक्षण:http://www.sqlfiddle.com/#!3/27821/6
लेकिन जैसा कि डीबेसमैन ने भी देखा है, एक ही कॉलम पर विभाजन और व्यवस्था करना बेकार है।
आपके पास इस तरह का डेटा सेट है:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','X'),
('A','X'),
('A','X'),
('B','Y'),
('B','Y'),
('C','Z'),
('C','Z');
फिर आप हाय, हो द्वारा विभाजन; और फिर आप हाय, हो द्वारा ऑर्डर करें। समान डेटा को क्रमांकित करने का कोई मतलब नहीं है :-) http://www.sqlfiddle.com/#!3/29ab8/3
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho) as nr
from tbl;
आउटपुट:
HI HO ROW_QUERY_A
A X 1
A X 2
A X 3
B Y 1
B Y 2
C Z 1
C Z 2
देखो? पंक्ति संख्याओं को समान संयोजन पर रखने की आवश्यकता क्यों है? आप ट्रिपल ए, एक्स, डबल बी, वाई, डबल सी, जेड पर क्या विश्लेषण करेंगे? :-)
आपको गैर-अद्वितीय कॉलम पर पार्टिशन का उपयोग करने की आवश्यकता है, फिर आप गैर-अद्वितीय कॉलम के अद्वितीय पर सॉर्ट करते हैं -इंग कॉलम। उदाहरण इसे और स्पष्ट करेगा:
create table tbl(hi varchar, ho varchar);
insert into tbl values
('A','D'),
('A','E'),
('A','F'),
('B','F'),
('B','E'),
('C','E'),
('C','D');
select
hi,ho,
row_number() over(partition by hi order by ho) as nr
from tbl;
PARTITION BY hi
गैर अद्वितीय कॉलम पर संचालित होता है, फिर प्रत्येक विभाजित कॉलम पर, आप इसके अद्वितीय कॉलम (हो), ORDER BY ho
पर ऑर्डर करते हैं
आउटपुट:
HI HO NR
A D 1
A E 2
A F 3
B E 1
B F 2
C D 1
C E 2
वह डेटा सेट अधिक समझ में आता है
लाइव परीक्षण:http://www.sqlfiddle.com/#!3/d0b44/1
और यह आपकी क्वेरी के समान है जिसमें PARTITION BY और ORDER BY दोनों पर समान कॉलम हैं:
select
hi,ho,
row_number() over(partition by hi,ho order by hi,ho) as nr
from tbl;
और यह आउटपुट है:
HI HO NR
A D 1
A E 1
A F 1
B E 1
B F 1
C D 1
C E 1
देखो? कोई मतलब नहीं?
लाइव परीक्षण:http://www.sqlfiddle.com/#!3/d0b44/3
अंत में यह सही प्रश्न हो सकता है:
SELECT cdt.*,
ROW_NUMBER ()
OVER (PARTITION BY cdt.country_code, cdt.account -- removed: cdt.currency
ORDER BY
-- removed: cdt.country_code, cdt.account,
cdt.currency) -- keep
seq_no
FROM CUSTOMER_DETAILS cdt