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

पोस्टग्रेज DISTINCT बनाम DISTINCT ON में क्या अंतर है?

DISTINCT और DISTINCT ON के शब्दार्थ पूरी तरह से अलग हैं।

पहले सिद्धांत

DISTINCT पूरे टपल पर लागू होता है। एक बार क्वेरी के परिणाम की गणना हो जाने के बाद, DISTINCT परिणाम से किसी भी डुप्लिकेट टुपल्स को हटा देता है।

उदाहरण के लिए, निम्न सामग्री वाली तालिका R मान लें:

#table r;
a | b 
---+---
1 | a
2 | b
3 | c
3 | d
2 | e
1 | a

(6 पंक्तियाँ)

R से अलग चुनें * का परिणाम होगा:

# select distinct * from r;
 a | b 
---+---
 1 | a
 3 | d
 2 | e
 2 | b
 3 | c
(5 rows)

ध्यान दें कि विशिष्ट अनुमानित विशेषताओं की पूरी सूची पर लागू होता है:इस प्रकार

select distinct * from R

अर्थ की दृष्टि से

. के बराबर है
select distinct a,b from R

आप जारी नहीं कर सकते

select a, distinct b From R

DISTINCT को सेलेक्ट का पालन करना चाहिए। यह पूरे टपल पर लागू होता है, न कि परिणाम की विशेषता पर।

DISTINCT चालू भाषा के लिए एक पोस्टग्रेस्क्ल जोड़ है। यह समूह के अनुसार समान है, लेकिन समान नहीं है।

इसका सिंटैक्स है:

 SELECT DISTINCT ON (attributeList) <rest as any query>

उदाहरण के लिए:

 SELECT DISTINCT ON (a) * from R

इसके शब्दार्थ का वर्णन इस प्रकार किया जा सकता है। सामान्य रूप से क्वेरी की गणना करें --- DISTINCT ON (a) के बिना --- लेकिन परिणाम के प्रक्षेपण से पहले, वर्तमान परिणाम को सॉर्ट करें और इसे DISTINCT ON (समूह के समान) में विशेषता सूची के अनुसार समूहित करें। अब, प्रत्येक समूह में पहले टपल का उपयोग करके प्रोजेक्शन करें और अन्य टुपल्स को अनदेखा करें।

उदाहरण:

select distinct * from r order by a;
     a | b 
    ---+---
     1 | a
     2 | e
     2 | b
     3 | c
     3 | d
    (5 rows)

फिर a के प्रत्येक भिन्न मान के लिए, पहला टपल लें। जो समान है:

 SELECT DISTINCT on (a) * from r;
  a | b 
 ---+---
 1 | a
 2 | b
 3 | c
 (3 rows)

कुछ DBMS (विशेषकर sqlite) आपको इस क्वेरी को चलाने की अनुमति देंगे:

 SELECT a,b from R group by a;

और यह आपको एक समान परिणाम देता है।

Postgresql इस क्वेरी की अनुमति देगा, अगर और केवल अगर a से b तक एक कार्यात्मक निर्भरता है। दूसरे शब्दों में, यह क्वेरी तब मान्य होगी जब संबंध R के किसी भी उदाहरण के लिए, प्रत्येक मान या a के लिए केवल एक अद्वितीय टपल हो (इस प्रकार पहला टपल चुनना नियतात्मक है:केवल एक टपल है)।

उदाहरण के लिए, यदि R की प्राथमिक कुंजी a है, तो a->b और:

SELECT a,b FROM R group by a

के समान है:

  SELECT DISTINCT on (a) a, b from r;

अब, अपनी समस्या पर वापस जाएं:

पहली क्वेरी:

SELECT DISTINCT count(dimension1)
FROM data_table;

आयाम 1 की गणना की गणना करता है (डेटा_टेबल में टुपल्स की संख्या जहां आयाम 1 शून्य नहीं है)। यह क्वेरी एक टपल लौटाती है, जो हमेशा अद्वितीय होती है (इसलिए DISTINCTअनावश्यक है)।

प्रश्न 2:

SELECT count(*)
FROM (SELECT DISTINCT ON (dimension1) dimension1
FROM data_table
GROUP BY dimension1) AS tmp_table;

यह एक क्वेरी में क्वेरी है। मुझे स्पष्टता के लिए इसे फिर से लिखने दें:

WITH tmp_table AS (
   SELECT DISTINCT ON (dimension1) 
     dimension1 FROM data_table
     GROUP by dimension1) 
SELECT count(*) from tmp_table

आइए पहले tmp_table की गणना करें। जैसा कि मैंने ऊपर उल्लेख किया है, आइए पहले DISTINCT ON को अनदेखा करें और बाकी की क्वेरी करें। यह आयाम 1 द्वारा एक समूह है। इसलिए क्वेरी के इस भाग के परिणामस्वरूप आयाम 1 के प्रति भिन्न मान में एक टपल होगा।

अब, DISTINCT चालू। यह फिर से आयाम 1 का उपयोग करता है। लेकिन आयाम 1 पहले से ही अद्वितीय है (समूह के कारण)। इसलिए यह सुपरफ्लो पर DISTINCT बनाता है (यह कुछ नहीं करता है)। अंतिम गणना समूह में सभी टुपल्स की गिनती है।

जैसा कि आप देख सकते हैं, निम्नलिखित क्वेरी में एक समानता है (यह एक विशेषता के साथ किसी भी संबंध पर लागू होता है):

SELECT (DISTINCT ON a) a
FROM R

और

SELECT a FROM R group by a

और

SELECT DISTINCT a FROM R

चेतावनी

किसी क्वेरी में DISTINCT ON परिणामों का उपयोग करना डेटाबेस के किसी दिए गए उदाहरण के लिए गैर-निर्धारक हो सकता है। दूसरे शब्दों में, क्वेरी समान तालिकाओं के लिए अलग-अलग परिणाम दे सकती है।

एक दिलचस्प पहलू

डिस्टिक्ट ऑन एक खराब . का अनुकरण करता है एक बहुत साफ तरीके से sqlite का व्यवहार। मान लें कि R की दो विशेषताएँ a और b हैं:

SELECT a, b FROM R group by a

एसक्यूएल में एक अवैध बयान है। फिर भी, यह sqlite पर चलता है। यह केवल a के समान मूल्यों के समूह में किसी भी टुपल्स से b का यादृच्छिक मान लेता है। Postgresql में यह कथन अवैध है। इसके बजाय, आपको DISTINCT ON का उपयोग करना चाहिए और लिखना चाहिए:

SELECT DISTINCT ON (a) a,b from R

उपदेशात्मक

DISTINCT ON किसी समूह में तब उपयोगी होता है जब आप किसी ऐसे मान तक पहुंचना चाहते हैं जो विशेषताओं के आधार पर समूह पर कार्यात्मक रूप से निर्भर होता है। दूसरे शब्दों में, यदि आप जानते हैं कि विशेषताओं के प्रत्येक समूह के लिए उनके पास हमेशा तीसरी विशेषता का समान मान होता है, तो विशेषताओं के उस समूह पर DISTINCT का उपयोग करें। अन्यथा आपको उस तीसरी विशेषता को पुनः प्राप्त करने के लिए जॉइन करना होगा।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. यदि अनुपलब्ध हो तो PostgreSQL पिछली पंक्ति से मान का उपयोग करता है

  2. Heroku - ActionView::Template::Error (PG::Error:ERROR:column category_products.desc मौजूद नहीं है)

  3. Postgres . में एन्क्रिप्टेड फ़ील्ड खोजना

  4. मोचा परीक्षण Knex के साथ PostgreSQL मुझे एक MigrationLocked त्रुटि दे रहा है

  5. त्रुटि:स्तंभ अनुक्रमणिका सीमा से बाहर है:1, स्तंभों की संख्या:0