SQL सर्वर: विभाजन BY और GROUP BY के बीच अंतर


365

मैं GROUP BYवर्षों से सभी प्रकार के कुल प्रश्नों का उपयोग कर रहा हूं । हाल ही में, मैंने कुछ कोड रिवर्स-इंजीनियरिंग किए हैं जो PARTITION BYएकत्रीकरण करने के लिए उपयोग करते हैं। सभी प्रलेखन के माध्यम से पढ़ने के बारे में PARTITION BY, जो मुझे पता चल सकता है , यह बहुत अच्छा लगता है GROUP BY, हो सकता है कि इसमें थोड़ी अतिरिक्त कार्यक्षमता के साथ जोड़ा गया हो? क्या वे एक ही सामान्य कार्यक्षमता के दो संस्करण हैं, या वे पूरी तरह से कुछ अलग हैं?

जवाबों:


440

वे विभिन्न स्थानों में उपयोग किए जाते हैं। group byपूरी क्वेरी को संशोधित करता है, जैसे:

select customerId, count(*) as orderCount
from Orders
group by customerId

लेकिन partition byसिर्फ एक विंडो फ़ंक्शन पर काम करता है , जैसे row_number:

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

एक group byसामान्य रूप से उन्हें रोल करके और प्रत्येक पंक्ति के लिए औसत या रकम की गणना करके लौटी पंक्तियों की संख्या कम कर देता है। partition byलौटी पंक्तियों की संख्या को प्रभावित नहीं करता है, लेकिन यह बदलता है कि विंडो फ़ंक्शन के परिणाम की गणना कैसे की जाती है।


23
अच्छा जवाब, क्या आप कृपया उनमें से प्रत्येक के लिए दिए गए परिणामों का एक नमूना लिखेंगे?
अश्कान मोबयेन खिबानी

2
@AshkanMobayenKhiabani आप नॉर्थविंड के खिलाफ दोनों प्रश्न चला सकते हैं, जो कि आपके sql सर्वर संस्करण के आधार पर डिफ़ॉल्ट रूप से स्थापित हो भी सकता है और नहीं भी। यदि नहीं, तो आप इसे डाउनलोड पृष्ठ पर खोज सकते हैं।
फेबचेज़ ला वाचे

15
@AshkanMobayenKhiabani अरुणाप्रसंत का जवाब नीचे दिए गए परिणाम दिखाते हैं जो आपको अधिक सीखने वाले हुप्स के माध्यम से कूदने का समय बचा सकता है और नॉर्थविंड सीखने का समय
प्रैक्सिटेल्स

1
विंडोज़ फ़ंक्शंस पर अधिक (SQL में): blog.jooq.org/2013/11/03/…-
datps

itcodehub.blogspot.com/2019/03/… - sql द्वारा समूह और विभाजन के बीच के अंतर के बारे में अधिक जानकारी और उदाहरण
xproph

252

हम एक सरल उदाहरण ले सकते हैं।

TableAनिम्नलिखित मूल्यों के साथ नामित तालिका पर विचार करें :

id  firstname                   lastname                    Mark
-------------------------------------------------------------------
1   arun                        prasanth                    40
2   ann                         antony                      45
3   sruthy                      abc                         41
6   new                         abc                         47
1   arun                        prasanth                    45
1   arun                        prasanth                    49
2   ann                         antony                      49

GROUP BY

एसक्यूएल ग्रुप बीओ क्लॉज का उपयोग कई रिकॉर्ड में डेटा एकत्र करने और एक या अधिक कॉलम द्वारा परिणामों को समूहीकृत करने के लिए एक सेलेक्ट स्टेटमेंट में किया जा सकता है।

अधिक सरल शब्दों में, ग्रुप बाय स्टेटमेंट का उपयोग कुल कार्यों के साथ संयोजन के रूप में किया जाता है ताकि परिणाम-समूह को एक या अधिक स्तंभों से जोड़ा जा सके।

वाक्य - विन्यास:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;

हम GROUP BYअपनी तालिका में आवेदन कर सकते हैं :

select SUM(Mark)marksum,firstname from TableA
group by id,firstName

परिणाम:

marksum  firstname
----------------
94      ann                      
134     arun                     
47      new                      
41      sruthy   

हमारी वास्तविक तालिका में हमारे पास 7 पंक्तियाँ हैं और जब हम लागू करते हैं GROUP BY id, तो सर्वर परिणाम के आधार पर समूह बनाता हैid :

सरल शब्दों में:

यहाँ GROUP BYसामान्य रूप से Sum()प्रत्येक पंक्ति के लिए उनकी गणना करके और उनकी गणना करके लौटी पंक्तियों की संख्या कम कर दी जाती है ।

PARTITION BY

पार्टिशन BY में जाने से पहले, हम OVERक्लॉज को देखते हैं:

MSDN परिभाषा के अनुसार:

कभी खंड किसी विंडो या उपयोगकर्ता द्वारा निर्दिष्ट क्वेरी परिणाम सेट में पंक्तियों के सेट को परिभाषित करता है। एक विंडो फ़ंक्शन तब विंडो में प्रत्येक पंक्ति के लिए एक मान की गणना करता है। आप मूविंग एवरेज, कम्युलेटिव एग्रीगेट, रनिंग टोटल, या प्रति समूह एन टॉप एन जैसे कुल मूल्यों की गणना करने के लिए कार्यों के साथ OVER क्लॉज का उपयोग कर सकते हैं।

विभाजन द्वारा दी गई पंक्तियों की संख्या कम नहीं होगी।

हम अपने उदाहरण तालिका में पार्टीशन लागू कर सकते हैं:

SELECT SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname FROM TableA

परिणाम:

marksum firstname 
-------------------
134     arun                     
134     arun                     
134     arun                     
94      ann                      
94      ann                      
41      sruthy                   
47      new  

परिणामों को देखें - यह पंक्तियों को विभाजित करेगा और GROUP BY के विपरीत सभी पंक्तियों को लौटाएगा ।


3
partition by पंक्तियों की संख्या को प्रभावित कर सकता है, यह सिर्फ पंक्तियों की संख्या को कम नहीं करेगा ।
जॉन

1
अगर मुझे दूसरी क्वेरी SELECTमें बदलना है तो क्या अंतर होगा SELECT DISTINCT? GROUP BYक्वेरी के समान डेटा-सेट लौटाएं नहीं ? एक या दूसरे को चुनने के क्या कारण हैं?
Erick 3E

3
@ Erick3E कृपया इस प्रश्न पर एक नज़र डालें। stackoverflow.com/questions/20375074/…
अरुणप्रशांत के.वी.

मुझे यह उत्तर बेहतर लगता है क्योंकि यह दर्शाता है कि विभाजन पर न्यूनतम / अधिकतम / सम आदि कार्य कैसे करते हैं। Row_Number () उदाहरण इसे स्पष्ट नहीं करता है। आम तौर पर मैं ग्रुप BY के साथ एक समग्र कार्य का उपयोग करता हूं, लेकिन सिर्फ यह देखा कि PARTITION-OVER के पास एक ही तरीके हैं और एक ही चीज को आश्चर्यचकित किया है, जो ओपी ने किया था - जो मुझे यहां ले जाते हैं। धन्यवाद!
रिपवैलन

53

partition byवास्तव में डेटा को रोल नहीं करता है। यह आपको प्रति समूह के आधार पर कुछ रीसेट करने की अनुमति देता है। उदाहरण के लिए, आप समूह के क्षेत्र में विभाजन करके और rownum()उस समूह के भीतर पंक्तियों का उपयोग करके एक समूह के भीतर एक आर्डिनल कॉलम प्राप्त कर सकते हैं । यह आपको कुछ देता है जो एक पहचान स्तंभ की तरह व्यवहार करता है जो प्रत्येक समूह की शुरुआत में रहता है।


43

विभाजन द्वारा विभाजन परिणाम को विभाजन में सेट करता है। विंडो फ़ंक्शन को प्रत्येक विभाजन के लिए अलग से लागू किया जाता है और प्रत्येक विभाजन के लिए गणना पुनरारंभ होती है।

इस लिंक पर मिला: OVER Clause


36

यह बिना रोल किए रोल-अप डेटा प्रदान करता है

मान लीजिए कि मैं बिक्री क्षेत्र की सापेक्ष स्थिति वापस करना चाहता हूं

विभाजन का उपयोग करके, मैं किसी दिए गए क्षेत्र और अधिकतम राशि के लिए बिक्री राशि को एक ही पंक्ति में सभी बिक्री क्षेत्रों में वापस कर सकता हूं ।

इसका मतलब है कि आपके पास डेटा दोहराव होगा, लेकिन यह अंत उपभोक्ता को इस अर्थ में सूट कर सकता है कि डेटा एकत्र किया गया है, लेकिन कोई डेटा नहीं खो गया है - जैसा कि ग्रुप बीवाई के साथ होगा।


3
सबसे अच्छा, सरलतम उत्तर।
tmthyjames

27

PARTITION BYविश्लेषणात्मक है, जबकि GROUP BYकुल है। उपयोग करने के लिए PARTITION BY, आपको इसे OVER क्लॉज के साथ रखना होगा ।


1
PARTITION BY is analyticइस सरल कथन ने मेरे लिए बहुत कुछ साफ कर दिया। +1।

यह वास्तव में सबसे सरल और सबसे अच्छा जवाब है।
jdmneon

22

मेरी समझ के अनुसार विभाजन तक समूह द्वारा लगभग समान है, लेकिन निम्नलिखित अंतरों के साथ:

वह समूह वास्तव में समूह द्वारा परिणाम प्रति समूह एक पंक्ति लौटाता है, जिसके परिणामस्वरूप SQL सर्वर केवल SELECT सूची एग्रीगेट फ़ंक्शन या कॉलम में अनुमति देता है जो समूह द्वारा क्लॉज का हिस्सा होते हैं (जिस स्थिति में SQL सर्वर गारंटी दे सकता है कि अद्वितीय हैं प्रत्येक समूह के लिए परिणाम)।

उदाहरण के लिए विचार करें MySQL जो समूह द्वारा परिभाषित चयनित सूची स्तंभों में होने की अनुमति देता है, जो खंड द्वारा परिभाषित नहीं है, इस स्थिति में अभी भी प्रति समूह एक पंक्ति वापस आ रही है, हालांकि यदि स्तंभ में अद्वितीय परिणाम नहीं हैं, तो कोई गारंटी नहीं है आउटपुट क्या होगा!

लेकिन विभाजन के साथ, हालांकि फ़ंक्शन के परिणाम समूह के साथ एक कुल समारोह के परिणामों के समान हैं, फिर भी आपको सामान्य परिणाम सेट मिल रहा है, जिसका अर्थ है कि प्रत्येक अंतर्निहित पंक्ति में एक पंक्ति मिल रही है, और प्रति पंक्ति एक पंक्ति नहीं है। समूह, और इसकी वजह से ऐसे कॉलम हो सकते हैं जो चयन सूची में प्रति समूह अद्वितीय नहीं हैं।

इसलिए एक सारांश के रूप में, Group By सबसे अच्छा होगा जब प्रति समूह एक पंक्ति के आउटपुट की आवश्यकता हो, और Partition By सबसे अच्छा होगा जब किसी को सभी पंक्तियों की आवश्यकता होगी लेकिन फिर भी समूह के आधार पर समुच्चय फ़ंक्शन चाहता है।

बेशक, प्रदर्शन के मुद्दे भी हो सकते हैं, http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7b7-0c60a2a55fba देखें


2

जब आप उपयोग करते हैं GROUP BY , तो परिणामी पंक्तियाँ आम तौर पर कम होंगी तो आने वाली पंक्तियाँ।

लेकिन, जब आप उपयोग करते हैं PARTITION BY, तो परिणामी पंक्ति गणना आवक के समान होनी चाहिए।


0

मान लीजिए हमारे पास 14 रिकॉर्ड हैं name तालिका में स्तंभ के

में group by

select name,count(*) as totalcount from person where name='Please fill out' group BY name;

यह सिंगल रो यानी 14 में काउंट देगा

लेकीन मे partition by

select row_number() over (partition by name) as total from person where name = 'Please fill out';

यह गिनती में वृद्धि की 14 पंक्तियाँ होंगी


0

छोटा सा अवलोकन। स्वचालन तंत्र गतिशील रूप से 'द्वारा विभाजन' का उपयोग कर SQL उत्पन्न करने के लिए 'समूह द्वारा' के संबंध में लागू करने के लिए बहुत सरल है। 'ग्रुप बाय' के मामले में, हमें 'सेलेक्ट' कॉलम की सामग्री का ध्यान रखना चाहिए।

मेरी अंग्रेजी के लिए खेद है।


0

यह वास्तव में अलग उपयोग परिदृश्यों है। जब आप GROUP BY का उपयोग करते हैं, तो आप स्तंभों के लिए कुछ अभिलेखों को मर्ज करते हैं जो समान हैं और आपके पास परिणाम सेट का एकत्रीकरण है।

हालाँकि जब आप अपने परिणाम सेट द्वारा पार्टीशन का उपयोग करते हैं, लेकिन आपके पास विंडो कार्यों पर एक एकत्रीकरण होता है और आप रिकॉर्ड्स को मर्ज नहीं करते हैं, तो आपके पास अभी भी रिकॉर्ड की एक ही गिनती होगी।

यहाँ एक रैली सहायक लेख है जो अंतर की व्याख्या करता है: http://alevryustemov.com/sql/sql-parts-n/


-1
-- BELOW IS A SAMPLE WHICH OUTLINES THE SIMPLE DIFFERENCES
-- READ IT AND THEN EXECUTE IT
-- THERE ARE THREE ROWS OF EACH COLOR INSERTED INTO THE TABLE
-- CREATE A database called testDB


-- use testDB
USE [TestDB]
GO


-- create Paints table
CREATE TABLE [dbo].[Paints](
    [Color] [varchar](50) NULL,
    [glossLevel] [varchar](50) NULL
) ON [PRIMARY]

GO


-- Populate Table
insert into paints (color, glossLevel)
select 'red', 'eggshell'
union
select 'red', 'glossy'
union
select 'red', 'flat'
union
select 'blue', 'eggshell'
union
select 'blue', 'glossy'
union
select 'blue', 'flat'
union
select 'orange', 'glossy'
union
select 'orange', 'flat'
union
select 'orange', 'eggshell'
union
select 'green', 'eggshell'
union
select 'green', 'glossy'
union
select 'green', 'flat'
union
select 'black', 'eggshell'
union
select 'black', 'glossy'
union
select 'black', 'flat'
union
select 'purple', 'eggshell'
union
select 'purple', 'glossy'
union
select 'purple', 'flat'
union
select 'salmon', 'eggshell'
union
select 'salmon', 'glossy'
union
select 'salmon', 'flat'


/*   COMPARE 'GROUP BY' color to 'OVER (PARTITION BY Color)'  */

-- GROUP BY Color 
-- row quantity defined by group by
-- aggregate (count(*)) defined by group by
select count(*) from paints
group by color

-- OVER (PARTITION BY... Color 
-- row quantity defined by main query
-- aggregate defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color)
from paints

/* COMPARE 'GROUP BY' color, glossLevel to 'OVER (PARTITION BY Color, GlossLevel)'  */

-- GROUP BY Color, GlossLevel
-- row quantity defined by GROUP BY
-- aggregate (count(*)) defined by GROUP BY
select count(*) from paints
group by color, glossLevel



-- Partition by Color, GlossLevel
-- row quantity defined by main query
-- aggregate (count(*)) defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color, glossLevel)
from paints
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.