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

मेरी पसंदीदा पोस्टग्रेएसक्यूएल क्वेरीज़ और वे क्यों मायने रखती हैं

डेटाबेस, टेबल, सामान्यीकरण, और एक ठोस बैकअप योजना हमें डेटा को स्टोर और बनाए रखने की अनुमति देती है।

वे संयुक्त सर्वोत्तम प्रथाएं, बदले में, हमें उस डेटा के साथ सहभागिता करने में सक्षम बनाती हैं। आज की डेटा-संचालित दुनिया में, डेटा मूल्यवान है। न केवल मूल्यवान, उत्पादों और सेवाओं द्वारा प्रदान किए गए अंतिम-उपयोगकर्ता समाधानों के लिए डेटा अक्सर महत्वपूर्ण होता है। क्वेरी और डेटा हेरफेर के माध्यम से डेटा से अंतर्दृष्टि निकालना, सवालों के जवाब देना, और सार्थक मेट्रिक्स सामान्य रूप से SQL का एक अभिन्न अंग है।

PostgreSQL अलग नहीं है।

किसी भी डेटा-संचालित पहलू में सफलता के लिए यह मूलभूत जड़ महत्वपूर्ण है।

नीचे, मैं 8 अलग-अलग प्रश्नों या प्रश्नों के प्रकारों का एक संयोजन प्रस्तुत करता हूं जो मुझे दिलचस्प और दिलचस्प लगे हैं, डेटा सेट का पता लगाने, अध्ययन करने, सीखने या अन्यथा हेरफेर करने के लिए।

वे महत्व के किसी भी क्रम में सूचीबद्ध नहीं हैं।

अधिकांश शायद परिचित पुराने दोस्त होंगे। शायद कुछ नए परिचित बन जाएंगे।

उपयोग किए गए नमूना तालिकाएं और डेटा उतना महत्वपूर्ण नहीं हैं जितना कि स्वयं प्रश्नों का वास्तविक निर्माण और प्रत्येक क्वेरी क्या लौटाती है, प्रदान करती है या प्रदान करती है। उनमें से कई नकली हैं और प्रदर्शन उद्देश्यों के लिए व्युत्पन्न हैं और उन्हें उनके मूल्यों में शाब्दिक रूप से नहीं लिया जाना चाहिए।

<एच2>1. बाएं शामिल हों, दाईं ओर किसी भी नल पर ध्यान दें...

मान लीजिए इस उदाहरण में, हमारे पास दो महीने की बिक्री चल रही है और दोनों को मिलाकर कुल मिला रहे हैं।

फिर भी, किसी कारण से, दूसरे महीने ने अपना वजन नहीं बढ़ाया और हम यह लक्षित करना चाहते हैं कि किस महीने में कौन सा महीना सुस्त रहा।

इस प्रदर्शन के लिए इन बिक्री को टेबल भुगतान और नकली_माह के रूप में दर्शाया गया है।

ध्यान दें:

  • हम केवल 2000 से अधिक के योग की जांच करेंगे।
  • हम आउटपुट को केवल 10 पंक्तियों तक सीमित कर देंगे।

शुरू करने के लिए, हमारे पास यह कॉमन टेबल एक्सप्रेशन (CTE) 'जनरेटिंग . है ' हमारे लिए नकली_माह तालिका, और उसके बाद की क्वेरी।

dvdrental=> WITH fake_month AS(
SELECT setup::date
FROM generate_series('2007-02-01', '2007-02-28', INTERVAL '1 day') AS setup
)
SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
LIMIT 10;
legit | sum | fake
-------+---------+------
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
20 | 3888.98 | 20
21 | 3786.14 | 21
(10 rows)

ऐसा लगता है जैसे दोनों महीनों ने वहां योगदान दिया हो। तो क्या यह हल हो गया?

इससे पहले कि हम इसे हल करने पर विचार करें, आइए ORDER BY क्लॉज पर जाएं।

बेशक, आप ASC या DESC द्वारा ऑर्डर कर सकते हैं।

हालांकि, आप NULLS द्वारा पहले या आखिरी में भी ऑर्डर कर सकते हैं और इससे चीजें थोड़ी बदल जाती हैं।

आइए इस क्वेरी को फिर से लिखें और पहले वैध कॉलम पर ORDER BY NULLS का उपयोग करें।

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

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
ORDER BY legit NULLS first
LIMIT 10;
legit | sum | fake
-------+---------+------
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
20 | 3888.98 | 20
21 | 3786.14 | 21
(10 rows)

कोई फर्क नहीं पड़ता।

क्या होगा अगर हम नकली कॉलम पर पहले NULLS द्वारा ऑर्डर करें? एक दाईं ओर जॉइन के पक्ष में?

आइए देखते हैं।

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
ORDER BY fake NULLS first
LIMIT 10;
legit | sum | fake
-------+---------+------
29 | 2717.60 |
30 | 5723.89 |
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
(10 rows)

अब हम कहीं पहुँच रहे हैं। हम देख सकते हैं कि 29 और 30 दिनों के लिए, परिणाम सेट के ऊपर से नकली कॉलम का आदेश दिया गया है।

पहले नकली NULLS द्वारा ORDER के कारण।

यह हमारे प्रश्न को हल करता है कि किस दिन 'बिक्री 2' बंद हो गई।

क्या आप सोच रहे हैं...

"क्या हम केवल नकली IS NULL के साथ फ़िल्टर कर सकते हैं? "

इस तरह:

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
WHERE date_part('day', fk.setup) IS NULL
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
LIMIT 10;
legit | sum | fake
-------+---------+------
29 | 2717.60 |
30 | 5723.89 |
(2 rows)

हाँ यह काम करता है। तो क्यों न केवल उस क्वेरी का उपयोग करें? यह क्यों मायने रखता है?

मुझे लगता है कि जॉइन के दाईं ओर तालिका के लिए पहले बाएं जॉइन और ऑर्डर बाय न्यूल का उपयोग करना, अपरिचित टेबल और डेटा सेट का पता लगाने का एक शानदार तरीका है।

यह पुष्टि करके कि क्या, यदि कोई है, डेटा 'गायब है ' पहले शामिल होने की स्थिति के उस तरफ; स्पष्टता और जागरूकता को बढ़ाता है, जिससे आप चीजों को अंतिम रूप देते हुए WHERE IS NULL क्लॉज के साथ सेट किए गए परिणामों को फ़िल्टर कर सकते हैं।

बेशक, तालिकाओं और डेटासेट से परिचित होने से यहां प्रस्तुत LEFT JOIN की आवश्यकता को संभावित रूप से समाप्त किया जा सकता है।

अन्वेषण के दौरान, कम से कम कोशिश करने के लिए PostgreSQL का उपयोग करने वाले किसी भी व्यक्ति के लिए यह एक योग्य प्रश्न है।

2. स्ट्रिंग संयोजन

संयोजन, दो तारों को जोड़ना या जोड़ना, परिणाम सेट के लिए एक प्रस्तुति विकल्प प्रदान करता है। कई 'चीजें ' को जोड़ा जा सकता है।

हालांकि, जैसा कि प्रलेखन में उल्लेख किया गया है, स्ट्रिंग कॉन्सटेनेशन ऑपरेटर ('||') गैर-स्ट्रिंग इनपुट को स्वीकार करता है, जब तक कि एक स्ट्रिंग है।

आइए नीचे दिए गए प्रश्नों के साथ कुछ उदाहरण देखें:

postgres=> SELECT 2||' times'||' 2 equals: '|| 2*2;
?column?
---------------------
2 times 2 equals: 4
(1 row)

जैसा कि ऊपर बताया गया है, हम देख सकते हैं, संख्याएं और तार सभी को एक साथ जोड़ा जा सकता है।

द '||' ऑपरेटर PostgreSQL में उपलब्ध उनमें से एक है।

concat() फ़ंक्शन कई तर्कों को स्वीकार करता है, उन सभी को वापसी पर संयोजित करता है।

क्रिया में उस फ़ंक्शन का एक उदाहरण यहां दिया गया है:

postgres=> SELECT concat('Josh ','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

हम चाहें तो दो से अधिक तर्क दे सकते हैं:

postgres=> SELECT concat('Josh',' ','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

आइए इन अगले उदाहरणों के साथ कुछ वास्तविक त्वरित नोट करें:

postgres=> SELECT CONCAT('Josh',NULL,'Otwell') AS first_name;
first_name
------------
JoshOtwell
(1 row)
postgres=> SELECT 'Josh '||NULL||'Otwell' AS first_name;
first_name
------------
(1 row)
postgres=> SELECT NULL||'Josh '||'Otwell' AS first_name;
first_name
------------
(1 row)
postgres=> SELECT CONCAT(NULL,'Josh','Otwell') AS first_name;
first_name
------------
JoshOtwell
(1 row)

ध्यान दें कि कॉनकैट () फ़ंक्शन NULL को अनदेखा करता है, चाहे पैरामीटर की सूची में कहीं भी रखा गया हो, जबकि स्ट्रिंग कॉन्सटेनेशन ऑपरेटर नहीं करता है।

जोड़ने के लिए स्ट्रिंग में कहीं भी मौजूद होने पर NULL लौटा दिया जाता है।

बस इसके प्रति जागरूक रहें।

मैन्युअल रूप से सम्मिलित करने के लिए स्ट्रिंग के भीतर शामिल करने के बजाय, PostgreSQL में एक concat_ws() फ़ंक्शन भी शामिल है जो एक स्ट्रिंग विभाजक को पहले पैरामीटर के रूप में स्वीकार करता है।

हम इन प्रश्नों के साथ इसका दौरा करेंगे:

postgres=> SELECT concat_ws('-',333,454,1919) AS cell_num;
cell_num
--------------
333-454-1919
(1 row)
postgres=> SELECT concat_ws(' ','Josh','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

concat_ws() तर्क के रूप में या तो संख्या या तार को स्वीकार करता है और जैसा कि ऊपर कहा गया है, विभाजक के रूप में पहले तर्क का उपयोग करता है।

concat_ws() NULL के साथ कैसा व्यवहार करता है?

postgres=> SELECT concat_ws('-',333,NULL,1919) AS cell_num;
cell_num
----------
333-1919
(1 row)
postgres=> SELECT concat_ws(NULL,333,454,1919) AS cell_num;
cell_num
----------
(1 row)

NULL को तब तक नज़रअंदाज़ किया जाता है जब तक कि यह concat_ws() को दिया गया सेपरेटर तर्क न हो।

फिर, सभी तर्कों को अनदेखा कर दिया जाता है और इसके बजाय NULL लौटा दिया जाता है।

संयोजन अच्छा है...

अब जब हमें समझ आ गया है कि संयोजन कैसे काम करता है, तो आइए इसके कुछ उदाहरणों को देखें।

नकली डीवीडी रेंटल डेटाबेस पर वापस जाएं

मान लीजिए कि हमें ग्राहकों के खाते को अपडेट करने के लिए एक मेमो भेजने के लिए उनके ईमेल पते के साथ पहले और अंतिम नामों की एक सूची संकलित करने की आवश्यकता है।

मैं संक्षिप्तता के लिए आउटपुट को केवल 10 पंक्तियों तक सीमित कर दूंगा, लेकिन फिर भी || . का प्रदर्शन कर रहा हूं ऑपरेटर।

dvdrental=> SELECT first_name||' '||last_name||'''s email address is: '||email AS name_and_email
FROM customer
LIMIT 10;
name_and_email
--------------------------------------------------------------------------
Jared Ely's email address is: [email protected]
Mary Smith's email address is: [email protected]
Patricia Johnson's email address is: [email protected]
Linda Williams's email address is: [email protected]
Barbara Jones's email address is: [email protected]
Elizabeth Brown's email address is: [email protected]
Jennifer Davis's email address is: [email protected]
Maria Miller's email address is: [email protected]
Susan Wilson's email address is: [email protected]
Margaret Moore's email address is: [email protected]
(10 rows)

ध्यान दें कि हमें प्रत्येक ग्राहक के लिए ईमेल पते पर कब्जा दिखाने के लिए एक अतिरिक्त एकल उद्धरण का उपयोग करते हुए, apostrophe s के साथ उपयोग किए गए एकल उद्धरण से बचना था।

आपको क्यों पता होना चाहिए?

ऐसे समय हो सकते हैं जब डेटा को संयोजित करना आपको उस डेटा सेट में बेहतर अंतर्दृष्टि और समझ के साथ प्रस्तुत करता है जिसके साथ आप काम कर रहे हैं। रिपोर्टिंग विकल्पों के साथ, साझा किए गए डेटासेट को दूसरों के साथ जोड़ने से संभावित रूप से वे (डेटा) अधिक पठनीय और सुपाच्य हो सकते हैं।

3. सबक्वेरी के साथ IN मान सूची की आपूर्ति करना

एक सबक्वेरी के कई शक्तिशाली उपयोग हैं। उनमें से, सदस्यता की जांच के लिए मूल्यों की एक IN सूची प्रदान करना एक सामान्य बात है।

यहाँ एक त्वरित उपयोग है।

मान लीजिए कि हमारे पास एक नकली डीवीडी रेंटल स्टोर में ग्राहक और भुगतान तालिकाएं हैं और हम अपने शीर्ष पांच सबसे अधिक खर्च करने वाले ग्राहकों को पुरस्कृत करना चाहते हैं, जिन्होंने 10 - 13 अप्रैल के दिनों में मूवी किराए पर ली थी।

कल्पना कीजिए कि यह एक विशेष लक्ष्य अवधि है। इसलिए यदि ग्राहक ने $30 से अधिक खर्च किए हैं, तो हम उन्हें स्वीकार करना चाहते हैं।

ध्यान रखें, इस प्रकार के प्रश्न को हल करने के लिए अन्य उपलब्ध विकल्प हैं (यानी, जुड़ना, एकाधिक चयनों से परिणाम कैप्चर करना, आदि...), फिर भी, उप-प्रश्न इसे भी संभाल सकते हैं।

हम यहां पूरे शेबंग से शुरुआत करेंगे। यह पूरी क्वेरी वह सब कुछ लौटा देती है जो हम इस विशेष प्रश्न के लिए चाहते हैं।

dvdrental=> SELECT first_name, last_name, email
FROM customer
WHERE customer_id IN (
SELECT customer_id FROM (
SELECT DISTINCT customer_id, SUM(amount)
FROM payment
WHERE extract(month from payment_date) = 4
AND extract(day from payment_date) BETWEEN 10 AND 13
GROUP BY customer_id
HAVING SUM(amount) > 30
ORDER BY SUM(amount) DESC
LIMIT 5) AS top_five);

इस उदाहरण में वास्तव में नेस्टेड सबक्वेरी हैं, जिनमें से एक व्युत्पन्न तालिका है।

आइए व्युत्पन्न तालिका, अंतरतम सबक्वेरी में ड्रिलिंग करके प्रारंभ करें।

यह सबक्वेरी अपने आप में एक स्टैंडअलोन सेलेक्ट स्टेटमेंट है, जो एक customer_id और एक SUM() को अमाउंट कॉलम पर लौटाता है।

WHERE और HAVING क्लॉज़ द्वारा जाँचे गए मानदंडों को पूरा करने वाले केवल वे ग्राहक ही कटौती करते हैं, जिन्हें LIMIT 5 के साथ और पतला किया जा रहा है;

आप अगली सबक्वायरी क्यों पूछते हैं?

क्या हम यहां सबसे बाहरी SELECT के WHERE customer_id IN भाग का उपयोग नहीं कर सकते?

आइए व्यावहारिक दृष्टिकोण से देखते हैं।

मैं सबक्वेरी से AS top_five को हटा दूंगा और इसके साथ सबसे बाहरी क्वेरी को अभी आज़माऊंगा:

dvdrental=> SELECT first_name, last_name, email
FROM customer
WHERE customer_id IN
(SELECT DISTINCT customer_id, SUM(amount)
FROM payment
WHERE extract(month from payment_date) = 4
AND extract(day from payment_date) BETWEEN 10 AND 13
GROUP BY customer_id
HAVING SUM(amount) > 30
ORDER BY SUM(amount) DESC
LIMIT 5);
ERROR: subquery has too many columns
LINE 3: WHERE customer_id IN (

यहां, IN सदस्यता का परीक्षण केवल customer_id कॉलम के साथ किया जा रहा है, फिर भी व्युत्पन्न तालिका दो कॉलम लौटाती है और PostgreSQL हमें इसकी जानकारी देता है।

एक उपाय दूसरे सबक्वेरी का उपयोग करना है। व्युत्पन्न तालिका परिणाम सेट से केवल customer_id का चयन करके, अगली आंतरिक नेस्टेड सबक्वेरी बनाता है।

अब IN विधेय में अंतिम परिणाम सेट करने के लिए Customer_id के लिए WHERE क्लॉज के विरुद्ध सदस्यता की जाँच करने के लिए एक कॉलम के मानों की कई पंक्तियाँ हैं।

यह क्यों मायने रखता है?

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

सोचिए अगर 100 होते? या अधिक?

'हार्ड-कोडिंग आईएन () सूची में वे सभी समस्यात्मक और त्रुटि-प्रवण हो सकते हैं क्योंकि मूल्यों की मात्रा बढ़ जाती है।

4. Generate_series ()

यह सेट रिटर्निंग फंक्शन, उपयोग करने और एक्सप्लोर करने के लिए आसान और सुपर मजेदार है। मैंने उपरोक्त उदाहरणों में Generate_series () का उपयोग किया है, लेकिन यह अपने आप में एक बात के योग्य है। फ़ंक्शन और क्षमताओं पर अधिक ध्यान केंद्रित करना।

मुझे उन तुलनात्मक प्रश्नों के लिए Generate_series() उपयोगी लगता है जहाँ कुछ, या सभी डेटा गायब हैं।

या जब मैं एक्सप्लोर कर रहा हूं तो केवल आंशिक डेटा ही उपलब्ध है। एक आसान उपयोग 'डमी डेटा . के साथ तालिकाओं को पॉप्युलेट करना है '।

शुरू करने के लिए, हम एक साधारण तालिका बनाएंगे:

trial=> CREATE TABLE tbl_1(
trial(> tb_id SERIAL PRIMARY KEY,
trial(> some_day DATE,
trial(> an_amt NUMERIC(4,2));
CREATE TABLE

फिर हमारे INSERT स्टेटमेंट के लिए VALUES के रूप में Generate_series () का उपयोग करें:

trial=> INSERT INTO tbl_1(some_day, an_amt)
VALUES(
generate_series('2018-04-01','2018-04-15',INTERVAL '1 day'),
generate_series(2.43, 34.20, 1.03));
INSERT 0 31

फिर दूसरी टेबल बनाएं

trial=> CREATE TABLE tbl_2(
tb2_id SERIAL PRIMARY KEY,
some_day2 DATE,
an_amt2 NUMERIC(4,2));
CREATE TABLE

साथ ही, INSERT कथन में generate_series() का उपयोग करके इसे पॉप्युलेट करें:

trial=> INSERT INTO tbl_2(some_day2, an_amt2)
VALUES(
generate_series('2018-05-16','2018-05-31',INTERVAL '1 day'),
generate_series(15.43, 31., 1.03));
INSERT 0 16

यह क्यों मायने रखता है?

दोहराने के लिए, Generate_series() नकली या अभ्यास डेटा बनाने के लिए बहुत उपयोगी है।

मैंने पाया है कि तुलना के लिए महीने या दिन की सीमाओं की नकल करना Generate_series () के साथ असाधारण है। अनुभाग 1 और वहां सीटीई देखें, इस प्रयोग को प्रदर्शित करता है।

Generate_series() के साथ पूर्ण डेटा का एक सेट बनाना और संग्रहीत डेटा के साथ तुलना करने के लिए उपयोग करना यह निर्धारित करने के लिए कि क्या कोई डेटा गुम है, भी बहुत महत्वपूर्ण है।

5. क्वेरी COUNT() कुल फ़ंक्शन के साथ है।

यह सरल, फिर भी प्रभावी समग्र कार्य किसी के भी शस्त्रागार में होना चाहिए। विशेष रूप से पहली बार टेबल या डेटा सेट की खोज करते समय।

मेरा मतलब है, क्या आप वाकई 'सब कुछ चुनना चाहते हैं ' 1M पंक्तियों वाली तालिका से?

COUNT(*) के साथ निर्धारित करें कि आपके लोड होने से पहले कितने रिकॉर्ड मौजूद हैं।

आइए जानें कि इस नकली DVD रेंटल तालिका में फ़िल्म तालिका में कितनी पंक्तियाँ हैं:

dvdrental=> SELECT COUNT(*)
dvdrental-> FROM film;
count
-------
1000
(1 row)

हालांकि 1M+ पंक्तियों जितना विस्तृत नहीं है, मुझे यकीन है कि आप इसकी उपयोगिता देखते हैं।

विशिष्ट पंक्तियों की संख्या वापस करने के लिए, COUNT(*) को WHERE क्लॉज के साथ फ़िल्टर किया जा सकता है।

आइए देखें कि कितनी फिल्मों को 'जी' रेटिंग मिली है:

dvdrental=> SELECT COUNT(*)
dvdrental-> FROM film
dvdrental-> WHERE rating = 'G';
count
-------
178
(1 row)

जागरूक होने के लिए COUNT() का एक और रूप है। COUNT(some_expression)

उनके बीच अंतर हैं:

  • COUNT(*) सभी इनपुट पंक्तियों (NULS और डुप्लीकेट सहित) का कुल रिटर्न देता है।
  • COUNT(some_expression ) गैर-नल इनपुट पंक्तियों की संख्या की गणना करता है।

जब DISTINCT कीवर्ड के संयोजन में उपयोग किया जाता है, तो COUNT() डुप्लिकेट प्रविष्टियों को समाप्त कर देगा और केवल अद्वितीय मान लौटाएगा।

आइए देखें कि कितने विशिष्ट प्रकार की रेटिंग मौजूद हैं, यह निर्धारित करने के लिए DISTINCT के साथ COUNT() का उपयोग करते हुए:

dvdrental=> SELECT COUNT(DISTINCT rating) FROM film;
count
-------
5
(1 row)

इस क्वेरी के साथ, हम जानते हैं कि रेटिंग 5 प्रकार की होती हैं।

यह क्यों मायने रखता है?

क्या ट्रैक किया जा रहा है या लक्षित किया जा रहा है, यह जानना महत्वपूर्ण हो सकता है कि कितने कुछ मौजूद हैं। इसलिए, COUNT(*) या COUNT(some_expression . का उपयोग करना ) इस प्रकार की चुनौतियों में सहायता करता है।

बस याद रखें COUNT(*) NULL को अनदेखा नहीं करता है। सभी पंक्तियाँ, डुप्लिकेट और NULL मान शामिल हैं, अंतिम संख्या के हिस्से के रूप में लौटाए जाते हैं।

6. CASE एक्सप्रेशन के साथ कई पंक्तियों को अपडेट करें।

मान लीजिए हमारे पास यह तालिका है:

trial=> SELECT * FROM reward_members;
rm_id | expense_amt | member_status
-------+-------------+---------------
1 | 1245.33 | gold
2 | 1300.49 | gold
3 | 900.20 | bronze
4 | 2534.44 | platinum
5 | 600.19 | bronze
6 | 1001.55 | silver
7 | 1097.99 | silver
8 | 3033.33 | platinum
(8 rows)

हमें Member_status कॉलम का नाम बदलने और 'ग्रुप . जोड़ने की जरूरत है ' प्रत्येक रिकॉर्ड के लिए मौजूद वर्तमान नाम के अंत तक।

शुरुआत के लिए, एकाधिक अलग-अलग अद्यतन विवरण इसे बिना किसी समस्या के पूरा करेंगे।

लेकिन, एक एकल CASE व्यंजक भी ऐसा ही कर सकता है।

trial=> UPDATE reward_members
SET member_status = (
CASE member_status
WHEN 'gold' THEN 'gold_group'
WHEN 'bronze' THEN 'bronze_group'
WHEN 'platinum' THEN 'platinum_group'
WHEN 'silver' THEN 'silver_group'
END
)
WHERE member_status IN ('gold', 'bronze','platinum', 'silver');
UPDATE 8

आइए परिवर्तन देखने के लिए तालिका को फिर से क्वेरी करें:

trial=> SELECT * FROM reward_members;
rm_id | expense_amt | member_status
-------+-------------+----------------
1 | 1245.33 | gold_group
2 | 1300.49 | gold_group
3 | 900.20 | bronze_group
4 | 2534.44 | platinum_group
5 | 600.19 | bronze_group
6 | 1001.55 | silver_group
7 | 1097.99 | silver_group
8 | 3033.33 | platinum_group
(8 rows)

सभी अपडेट सफल रहे।

यह क्यों मायने रखता है?

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

फिर भी, CASE एक्सप्रेशन के साथ UPDATE का उपयोग करके, हम इसके बजाय केवल एक क्वेरी भेज रहे हैं।

7. कॉपी करें और \कॉपी करें

PostgreSQL फाइलों और तालिकाओं के बीच डेटा निर्यात करने के लिए COPY, एक कमांड प्रदान करता है।

सुनिश्चित करें और COPY के साथ उपलब्ध विकल्पों की प्रचुर संख्या को देखने के लिए दिए गए लिंक पर जाएं।

कॉपी से संबंधित एक महत्वपूर्ण नोट। इस कमांड को निष्पादित करने के लिए सुपरयुसर भूमिका विशेषाधिकार की आवश्यकता है।

psql मेटा-कमांड \copy उन उपयोगकर्ताओं के लिए एक विकल्प है जो इस भूमिका विशेषता को नहीं समझते हैं। हम शीघ्र ही उस आदेश पर जाएंगे।

सबसे पहले, स्थानीय मशीन पर CSV फ़ाइल में कुछ कॉलम निर्यात करने के लिए COPY कमांड चलाते हैं।

मान लें कि हमारे पास निर्यात के लिए यह क्वेरी परिणाम है:

trial=# SELECT expense_amt, member_status
trial-# FROM reward_members
trial-# WHERE member_status = 'gold_group';
expense_amt | member_status
-------------+---------------
1245.33 | gold_group
1300.49 | gold_group
(2 rows)

कॉपी के साथ, हम इस निर्यात को पूरा करने के लिए उस सेलेक्ट स्टेटमेंट का उपयोग कर सकते हैं।

trial=# COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/home/linux_user_here/awards_to_honor.csv'
DELIMITER ','
CSV HEADER;
COPY 2

*नोट:दस्तावेज़ीकरण के अनुसार, क्वेरी कोष्ठक के भीतर होनी चाहिए।

आइए अब उस फ़ाइल की सामग्री की जाँच करें:

$ cat awards_to_honor.csv
expense_amt,member_status
1245.33,gold_group
1300.49,gold_group

हम देख सकते हैं कि पहली पंक्ति में HEADER है (जो कॉलम नाम हैं) और दोनों पंक्तियों में WHERE क्लॉज फ़िल्टर से लौटाए गए दोनों कॉलमों के लिए व्यय_एएमटी और सदस्य_स्टेटस डेटा है।

उपरोक्त COPY कमांड को निष्पादित करने से मुझे एक और महत्वपूर्ण चेतावनी मिली।

उपयोगकर्ता के पास OS स्तर पर फ़ाइल में लिखने का विशेषाधिकार होना चाहिए।

मेरे मामले में, इसके साथ तय:

$ sudo chown postgres awards_to_honor.csv

आप इस समस्या से बचने के लिए उस सिस्टम फ़ाइल को लिख सकते हैं जिस पर वर्तमान उपयोगकर्ता की पहुँच है जैसे /tmp (नीचे दिखाया गया है।)

trial=# COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/tmp/awards_to_honor.csv'
DELIMITER ','
CSV HEADER;
COPY 2

हालाँकि, SUPERUSER विशेषता के बिना मेरी एक परीक्षण भूमिका, /tmp फ़ाइल में लिखने में समस्या आ गई।

पुष्टि के लिए नीचे देखें:

trial=# SET role log_user; -- changing from postgres user to log_user
SET

अब उसी COPY कमांड का प्रयास करते हुए, /tmp फ़ोल्डर में लिख रहे हैं

trial=> COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/tmp/awards_to_honor2.csv'
DELIMITER ','
CSV HEADER;
ERROR: must be superuser to COPY to or from a file
HINT: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

शायद एक बेहतर उपाय, जैसा कि HINT में सुझाया गया है:, SUPERUSER विशेषता के बिना भूमिकाओं के लिए, psql \copy मेटा-कमांड है।

आइए एक समान प्रकार के कमांड को \copy के साथ उसी भूमिका का उपयोग करने के बजाय, उस SUPERUSER विशेषता की आवश्यकता के बिना पूरा करें।

trial=> \copy (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'silver_group')
TO '/home/linux_user_here/more_awards.csv'
DELIMITER ','
CSV HEADER;
COPY 2

वहां कोई समस्या नहीं है।

और फाइलों की सामग्री,

$ cat more_awards.csv
expense_amt,member_status
1001.55,silver_group
1097.99,silver_group

/tmp फ़ोल्डर के लिए भी काम करता है:

trial=> \copy (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'silver_group')
TO '/tmp/more_awards.csv'
DELIMITER ','
CSV HEADER;
COPY 2

लिखित फ़ाइल में भी वही सामग्री मौजूद है:

trial=> \! cat /tmp/more_awards.csv
expense_amt,member_status
1001.55,silver_group
1097.99,silver_group

यह क्यों मायने रखता है?

फ़ाइलों के माध्यम से PostgreSQL में डेटा आयात करना एक अचूक बल्क अपलोड विधि है। हालांकि इस ब्लॉग पोस्ट में सभी शामिल नहीं हैं, कॉपी और \कॉपी दोनों, विभिन्न फ़ाइल स्वरूपों और एक्सटेंशन के साथ काम करने के लिए कई विकल्प प्रदान करते हैं।

एक ही टोकन पर, टेबल या विशिष्ट कॉलम से डेटा निर्यात करना इन दोनों आदेशों के साथ भी आसानी से नियंत्रित किया जाता है।

8. psql \help मेटा-कमांड

आप psql कमांड-लाइन सत्र में हैं। CREATE INDEX कमांड सिंटैक्स के बारे में उत्सुक हैं?

किसी ब्राउज़र या किसी अन्य दस्तावेज़ पर जाने की आवश्यकता नहीं है।

इसके बजाय इसे आजमाएं:

trial=> \help CREATE INDEX
Command: CREATE INDEX
Description: define a new index
Syntax:
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON table_name [ USING method ]
( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
[ WITH ( storage_parameter = value [, ... ] ) ]
[ TABLESPACE tablespace_name ]
[ WHERE predicate ]

यह जानने के लिए कि कौन सा सहायता पाठ उपलब्ध है, आप स्वयं \help चला सकते हैं और उपलब्ध विकल्पों की सूची प्राप्त कर सकते हैं।

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

यह क्यों मायने रखता है?

तथ्य यह है कि यह मेटा-कमांड उपयोग में बहुत आसान, शक्तिशाली और सुविधाजनक है, इसका उल्लेख करने के लिए पर्याप्त पेशेवर हैं। इसने मुझे अन्य दस्तावेज़ों में खोज करने में लगने वाले समय की बचत की है। और हां, एक नौसिखिया होने के नाते, मैं इसे अक्सर इस्तेमाल करता हूं!

निष्कर्ष

यह एक विस्तृत सूची नहीं है। न ही 'सब अंत हो ' प्रश्नों और डेटा हेरफेर के।

केवल उन लोगों पर मेरा ध्यान है जो मेरी रुचि को बढ़ाते हैं और मुझसे बात करते हैं क्योंकि मैं सीखना जारी रखता हूं और एक SQL डेवलपर भूमिका में विकसित होता हूं। मुझे उम्मीद है कि इस ब्लॉग पोस्ट के माध्यम से, आप उपरोक्त प्रश्नों और आदेशों के लिए उपयोग के मामले पाएंगे, जहां आपको उपयुक्त लगे उन्हें लागू करना।


  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. मैं Postgresql SCRAM प्रमाणीकरण समस्या को कैसे हल कर सकता हूं?

  3. PostgreSQL को कभी-कभी खराब क्वेरी प्लान चुनने से रोकें

  4. PostgreSQL में IN बनाम कोई भी ऑपरेटर

  5. Psql का उपयोग करके PostgreSQL में डेटाबेस और तालिकाओं को कैसे सूचीबद्ध करें