2013-03-02 13 views
10

के साथ unnest मैं postgreSQL 9.1 का उपयोग करता हूं। मेरे डेटाबेस मेंपोस्टग्रेएसक्यूएल खाली सरणी

id | ... | values 
----------------------- 
1 | ... | {1,2,3} 
2 | ... | {} 

जहां आईडी एक पूर्णांक है और मान एक पूर्णांक सरणी है। सरणी खाली हो सकती है।

मुझे इस सूची को अनदेखा करने की आवश्यकता है। अगर मैं

select id, ..., unnest(values) 
from table 

क्वेरी मैं आईडी के लिए तीन पंक्तियों मिल = 1 (की उम्मीद के रूप में) और आईडी = 2. के लिए कोई लाइनों वहाँ एक रास्ता

id | ... | unnest 
------------------- 
1 | ... | 1 
1 | ... | 2 
1 | ... | 3 
2 | ... | null 

यानी एक प्रश्न की तरह एक परिणाम प्राप्त करने के लिए है जो उन रेखाओं को भी शामिल किया गया है जिनमें खाली सरणी है? कि बड़े तालिकाओं के लिए क्वेरी बुरी तरह से प्रदर्शन किया जाएगा,

SELECT t.id, u.u 
    FROM tab t 
    LEFT JOIN (SELECT id, unnest(vals) u FROM tab) u 
    USING (id); 

नोट:

उत्तर

9
select id, 
     case 
     when int_values is null or array_length(int_values,1) is null then null 
     else unnest(int_values) 
     end as value 
from the_table; 

(ध्यान दें कि मैं values रूप int_values करने के लिए स्तंभ values नाम बदलकर एक आरक्षित शब्द है और एक स्तंभ नाम के रूप में नहीं किया जाना चाहिए)।

SQLFiddle: http://sqlfiddle.com/#!1/a0bb4/1


Postgres 10 किसी भी अधिक unnest() उस तरह का उपयोग करने की अनुमति नहीं है। कि इस सरल और तेजी से हो सकता है http://rextester.com/ALNX23313

+0

यह पोस्टग्रेस्क्ल 10 –

+0

@ ब्लडिंगफिंगर्स पर काम नहीं करेगा: मेरा अपडेट देखें –

0

आप (भी SQL Fiddle पर) स्वयं LEFT JOIN उपयोग करने के लिए, इस तरह की आवश्यकता होगी।

1
select id, 
    unnest (
     "values" 
     || 
     (array[null]::integer[])[1:(array_upper("values", 1) is null)::integer] 
    ) 
from "table" 
3

इस सवाल यह मुझे मारा समीक्षा पर:

आप एक पार्श्व में शामिल होने के उपयोग करने की आवश्यकता:

select id, t.i 
from the_table 
    cross join lateral unnest(coalesce(nullif(int_values,'{}'),array[null::int])) as t(i); 

ऑनलाइन उदाहरण।
currently accepted solution by @a_horse के तर्क रिवर्स:

SELECT id, CASE WHEN values <> '{}' THEN unnest(values) END AS value 
FROM tbl 
  • यह एक खाली सरणी के लिए और साथ ही एक NULL सरणी के लिए value में NULL के साथ एक पंक्ति देता है, क्योंकि केवल में तत्वों के साथ एक सरणी यह values <> '{}' परीक्षण में TRUE का उत्पादन करता है।

  • किसी भी प्रकार के सरणी के लिए काम करता है, क्योंकि शाब्दिक '{}' स्वचालित रूप से मिलान करने वाले प्रकार से मिल जाता है।

  • स्पष्ट ELSE शाखा के बिना, CASENULL देता है, जो हम वैसे भी चाहते हैं।

  • NULL तत्वों के साथ Arrays परवाह किए बिना पंक्तियों को वापस कर देगा।
    हालांकि। मैं वहाँ एक विसंगति पाया और उस विषय में एक प्रश्न पोस्ट:

    पता चला है कि एक बग स्नातकोत्तर 9.3+ के लिए अपनी रिपोर्ट के बाद तय किया गया था हो सकता है।

संबंधित मुद्दे