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

रिकॉर्ड के कॉलम के माध्यम से लूप

जैसा कि @ पावेल ने समझाया, एक रिकॉर्ड को पार करना संभव नहीं है, जैसे आप एक सरणी को पार कर सकते हैं। लेकिन इसके आसपास कई तरीके हैं - आपकी सटीक आवश्यकताओं के आधार पर। अंततः, चूंकि आप एक ही कॉलम में सभी मानों को वापस करना चाहते हैं, इसलिए आपको उन्हें एक ही प्रकार में डालना होगा - text स्पष्ट सामान्य आधार है, क्योंकि हर प्रकार के लिए एक पाठ प्रतिनिधित्व है।

त्वरित और गंदा

मान लें, आपके पास integer वाली एक तालिका है , एक text और एक date कॉलम।

CREATE TEMP TABLE tbl(a int, b text, c date);
INSERT INTO tbl VALUES
 (1, '1text',     '2012-10-01')
,(2, '2text',     '2012-10-02')
,(3, ',3,ex,',    '2012-10-03')  -- text with commas
,(4, '",4,"ex,"', '2012-10-04')  -- text with commas and double quotes

तब समाधान सरल हो सकता है:

SELECT unnest(string_to_array(trim(t::text, '()'), ','))
FROM   tbl t;

पहली दो पंक्तियों के लिए काम करता है, लेकिन पंक्ति 3 और 4 के विशेष मामलों के लिए विफल रहता है।
आप पाठ प्रतिनिधित्व में अल्पविराम के साथ समस्या को आसानी से हल कर सकते हैं:

SELECT unnest(('{' || trim(t::text, '()') || '}')::text[])
FROM   tbl t
WHERE  a < 4;

यह ठीक काम करेगा - लाइन 4 को छोड़कर जिसमें टेक्स्ट प्रतिनिधित्व में डबल कोट्स हैं। जिन्हें दुगना करके भाग निकले हैं। लेकिन ऐरे कंस्ट्रक्टर को उन्हें \ . से बचने की आवश्यकता होगी . निश्चित नहीं है कि यह असंगति क्यों है...

SELECT ('{' || trim(t::text, '()') || '}') FROM tbl t WHERE a = 4

पैदावार:

{4,""",4,""ex,""",2012-10-04}

लेकिन आपको इसकी आवश्यकता होगी:

SELECT '{4,"\",4,\"ex,\"",2012-10-04}'::text[];  -- works

उचित समाधान

यदि आप कॉलम के नाम पहले से जानते हैं, तो एक साफ समाधान आसान होगा:

SELECT unnest(ARRAY[a::text,b::text,c::text])
FROM tbl

चूंकि आप अच्छी तरह से ज्ञात प्रकार के रिकॉर्ड पर काम करते हैं, इसलिए आप केवल सिस्टम कैटलॉग को क्वेरी कर सकते हैं:

SELECT string_agg(a.attname || '::text', ',' ORDER  BY a.attnum)
FROM   pg_catalog.pg_attribute a 
WHERE  a.attrelid = 'tbl'::regclass
AND    a.attnum > 0
AND    a.attisdropped = FALSE

इसे डायनामिक SQL वाले फ़ंक्शन में रखें:

CREATE OR REPLACE FUNCTION unnest_table(_tbl text)
  RETURNS SETOF text LANGUAGE plpgsql AS
$func$
BEGIN

RETURN QUERY EXECUTE '
SELECT unnest(ARRAY[' || (
    SELECT string_agg(a.attname || '::text', ',' ORDER  BY a.attnum)
    FROM   pg_catalog.pg_attribute a 
    WHERE  a.attrelid = _tbl::regclass
    AND    a.attnum > 0
    AND    a.attisdropped = false
    ) || '])
FROM   ' || _tbl::regclass;

END
$func$;

कॉल करें:

SELECT unnest_table('tbl') AS val

रिटर्न:

val
-----
1
1text
2012-10-01
2
2text
2012-10-02
3
,3,ex,
2012-10-03
4
",4,"ex,"
2012-10-04

यह अतिरिक्त मॉड्यूल स्थापित किए बिना काम करता है। दूसरा विकल्प यह है कि hstore एक्सटेंशन इंस्टॉल करें और इसे @Craig के प्रदर्शन की तरह इस्तेमाल करें।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. पीजी मणि स्थापित करने का प्रयास करते समय 'libpq-fe.h शीर्षलेख नहीं मिल रहा है

  2. PostgreSQL उपयोगकर्ता अनुमतियाँ

  3. LIMIT 1 . के साथ अनुक्रमित ORDER BY

  4. SQLAlchemy, Psycopg2 और Postgresql COPY

  5. रेल का दायरा - जहां सटीक मिलान में