PostgreSQL में VALUES का उपयोग करके एक अस्थायी तालिका कैसे बनाएं


38

मैं PostgreSQL सीख रहा हूं और यह पता लगाने की कोशिश कर रहा हूं WITHकि डिबगिंग उद्देश्यों के लिए एक अस्थायी टेबल या एक घोषणा कैसे बनाई जा सकती है जिसका उपयोग नियमित टेबल के स्थान पर किया जा सकता है।

मैंने क्रिएट टेबल के लिए प्रलेखन को देखा और यह कहता है कि इसे VALUESएक क्वेरी के रूप में इस्तेमाल किया जा सकता है लेकिन कोई उदाहरण नहीं देता; इसके साथ VALUESजुड़े क्लॉज के लिए प्रलेखन में एक उदाहरण भी नहीं है?

इसलिए, मैंने एक सरल परीक्षण इस प्रकार लिखा है:

DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup (
  key integer,
  val numeric
) AS
VALUES (0,-99999), (1,100);

लेकिन PostgreSQL (9.3) के बारे में शिकायत कर रहा है

"AS" पर या उसके पास सिंटैक्स त्रुटि

मेरे प्रश्न हैं:

  1. मैं ऊपर दिए गए कथन को कैसे ठीक कर सकता हूं?

  2. मैं इसे एक में इस्तेमाल करने के लिए कैसे अनुकूलित कर सकता हूं WITH block?

अग्रिम में धन्यवाद।


मैंने इस सवाल का कुछ और आधुनिक सलाह के साथ जवाब देने की कोशिश की (जैसा कि चुना गया जवाब एक गैर-मानकीकृत सिंटैक्स का उपयोग कर रहा है) dba.stackexchange.com/a/201575/2639
इवान कैरोल

जवाबों:


46

संपादित करें: मैं मूल स्वीकार किए गए उत्तर को छोड़ रहा हूं जैसा कि यह है, लेकिन कृपया ध्यान दें कि नीचे संपादित करें, जैसा कि a_horse_with_no_name द्वारा सुझाया गया है, VALUES का उपयोग करके एक अस्थायी तालिका बनाने के लिए पसंदीदा तरीका है।

यदि आप केवल कुछ मानों का चयन करना चाहते हैं, तो केवल एक तालिका बनाने और उसमें सम्मिलित होने के बजाय, आप कुछ ऐसा कर सकते हैं:

WITH  vals (k,v) AS (VALUES (0,-9999), (1, 100)) 
SELECT * FROM vals;

वास्तव में एक समान फैशन में एक अस्थायी तालिका बनाने के लिए, उपयोग करें:

WITH  vals (k,v) AS (VALUES (0,-9999), (1, 100)) 
SELECT * INTO temporary table temp_table FROM vals;

EDIT: जैसा कि डॉक्स में a_horse_with_no_name द्वारा इंगित किया गया है, यह बताता है कि CREATE TABLE AS...कार्यात्मक रूप से समान है SELECT INTO ..., लेकिन यह कि पूर्व उत्तरार्द्ध का एक सुपरसेट है और SELECT INTOइसका उपयोग अस्थायी चर के मान को असाइन करने के लिए plpgslq में किया जाता है - इसलिए यह इसमें विफल होगा। उस मामले में। इसलिए, जबकि उपरोक्त उदाहरण सादे एसक्यूएल के लिए मान्य हैं, CREATE TABLEप्रपत्र को प्राथमिकता दी जानी चाहिए।

CREATE TEMP TABLE temp_table AS                                     
WITH t (k, v) AS (
 VALUES
 (0::int,-99999::numeric), 
 (1::int,100::numeric)
)
SELECT * FROM t;

नोट, a_horse_with_no_name द्वारा टिप्पणियों से भी, और ओपी के मूल प्रश्न में, इसमें मान सूची के अंदर सही डेटाटाइप्स में एक कास्ट शामिल है और एक सीटीई (विथ) स्टेटमेंट का उपयोग करता है।

इसके अलावा, जैसा कि इवान काररोल के जवाब में कहा गया है, एक सीटीई क्वेरी एक अनुकूलन बाड़ है , यानी, सीटीई हमेशा भौतिक होता है। CTEs का उपयोग करने के कई अच्छे कारण हैं, लेकिन ध्यान से उपयोग न किए जाने पर काफी महत्वपूर्ण प्रदर्शन हो सकता है। हालांकि, ऐसे कई उदाहरण हैं, जहां अनुकूलन बाड़ वास्तव में प्रदर्शन को बढ़ा सकते हैं, इसलिए यह आँख बंद करके बचने के लिए नहीं बल्कि जागरूक होने के लिए कुछ है।


12
डॉक्स से : " क्रिएट टेबल एएस, कार्यात्मक रूप से
सिलेक्ट इन्टो के

अनुकूलन बाड़ जरूरी एक बुरी चीज नहीं है। मैंने कई बयानों को देखा है जिनकी वजह से मैं सामूहिक रूप से तेजी से दौड़ सकता हूं।
a_horse_with_no_name

यकीन है, मैंने भी स्पष्ट किया है। मैं हर समय एक स्थानिक संदर्भ में सीटीई का उपयोग करता हूं। यदि आपके पास ऐसा कुछ है जहां WHERE ST_Intersects(geom, (SELECT geom FROM sometable)या WHERE ST_Intersects(geom, ST_Buffer(anothergeom, 10)फिर अक्सर क्वेरी प्लानर के साथ क्लॉज होता है, तो स्थानिक इंडेक्स का उपयोग नहीं किया जाता है क्योंकि जियोम कॉलम अब सर्गेबल नहीं है। यदि आप प्रारंभिक CTE में अपनी रुचि का क्षेत्र बनाते हैं, तो यह समस्या दूर हो जाती है। यह सुपर सुविधाजनक भी है, यदि आप एक ही क्वेरी में एक ही aoi को एक से अधिक अभिव्यक्तियों में उपयोग करना चाहते हैं, जो कि GIS संदर्भ में असामान्य नहीं है।
जॉन पॉवेल

25

create table as एक चयन कथन की आवश्यकता है:

DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup 
as 
select *
from (
   VALUES 
    (0::int,-99999::numeric), 
    (1::int, 100::numeric)
) as t (key, value);

CTE का उपयोग करने के लिए आप इसे फिर से लिख सकते हैं:

create temp table lookup 
as 
with t (key, value) as (
  values 
    (0::int,-99999::numeric), 
    (1::int,100::numeric)
)
select * from t;

1
टिप्पणी के लिए धन्यवाद। डॉक्स में बताए गए कारणों से आप स्पष्ट रूप से बेहतर हैं। मैंने अपना उत्तर संपादित किया है, भले ही लगभग 5 साल देर हो गई हो।
जॉन पॉवेल

11

मुद्दा डेटाटाइप्स है। यदि आप उन्हें हटा देते हैं, तो कथन काम करेगा:

CREATE TEMP TABLE lookup
  (key, val) AS
VALUES 
  (0, -99999), 
  (1, 100) ;

आप पहली पंक्ति के मानों को टाइप करके परिभाषित कर सकते हैं:

CREATE TEMP TABLE lookup 
  (key, val) AS
VALUES 
  (0::bigint, -99999::int), 
  (1, 100) ;

3

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

SELECT  *
FROM    (VALUES(0::INT, -99999::NUMERIC), (1, 100)) AS lookup(key, val)

तब आप कार्टेसियन उत्पाद को एक CROSS JOIN(जहां दूसरा संबंध हो सकता है, निश्चित रूप से, एक नियमित तालिका, दृश्य, आदि) प्राप्त कर सकते हैं। उदाहरण के लिए:

SELECT  *
FROM    (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
       ,(VALUES('Red'), ('White'), ('Blue')) AS colors(color);

कौन सी पैदावार:

key |val    |color |
----|-------|------|
0   |-99999 |Red   |
1   |100    |Red   |
0   |-99999 |White |
1   |100    |White |
0   |-99999 |Blue  |
1   |100    |Blue  |

या JOINकिसी अन्य रिश्ते के साथ मूल्य (जो फिर से एक नियमित तालिका, दृश्य आदि हो सकते हैं), उदाहरण के लिए:

SELECT  *
FROM    (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
  JOIN  (VALUES('Red', 1), ('White', 0), ('Blue', 1)) AS colors(color, lookup_key)
          ON colors.lookup_key = lookup.key;

कौन सी पैदावार:

key |val    |color |lookup_key |
----|-------|------|-----------|
1   |100    |Red   |1          |
0   |-99999 |White |0          |
1   |100    |Blue  |1          |

ठीक है, लेकिन सवाल था "कैसे एक अस्थायी तालिका बनाने के लिए ...?"
ypercube y

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

1
हो सकता है कि ओपी ने सिर्फ उदाहरण के लिए कुछ ऐसा किया हो जो प्रश्न के रूप में पोस्ट करना आसान हो, लेकिन वास्तविक डेटा में हजारों मान हैं?
स्टेनियस

ओपी ने विशेष रूप से मूल्यों का उपयोग करते हुए कहा, इसलिए मेरा जवाब अभी भी लागू होता है जैसा कि ठीक यही करता है
isapir

2

पहले हमेशा मानकीकृत का उपयोग करें CREATE TABLE AS, SELECT INTOजैसा कि अन्य उत्तरों में सुझाया गया है एक दशक से अधिक के लिए एक सिंट्रेक्ट सिंटैक्स। आप एक सीटीई के साथ उपयोग कर सकते हैंCREATE TABLE AS

हालांकि यहाँ कई उत्तर CTE का उपयोग करने का सुझाव दे रहे हैं, लेकिन यह बेहतर नहीं है। वास्तव में, यह कुछ हद तक धीमा होने की संभावना है। बस इसे एक मेज के रूप में लपेटो।

DROP TABLE IF EXISTS lookup;

CREATE TEMP TABLE lookup(key, value) AS
  VALUES
  (0::int,-99999::numeric),
  (1,100);

यदि आपको एक चयन कथन लिखना है तो आप वह भी कर सकते हैं (और आपको CTE की आवश्यकता नहीं है)।

CREATE TEMP TABLE lookup(key, value) AS
  SELECT key::int, value::numeric
  FROM ( VALUES
    (0::int,-99999::numeric),
    (1,100)
  ) AS t(key, value);

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

\timing
CREATE TABLE foo AS
  SELECT * FROM generate_series(1,1e7);
Time: 5699.070 ms

CREATE TABLE foo AS
  WITH t AS ( SELECT * FROM generate_series(1,1e7) ) 
  SELECT * FROM t;
Time: 6484.516 ms

मैंने मानक को प्रतिबिंबित करने के लिए उत्तर को अपडेट किया है, और इंगित करता है कि कैसे स्वीकार किए गए उत्तर हमेशा क्रिएट टेबल एएस के बराबर नहीं है और ऑप्टिमाइज़ेशन बाड़ पर एक टिप्पणी जोड़ दी है, जो ऊपर लाने के लिए एक बहुत अच्छा बिंदु है। CTE बहुत सारे फायदे लाते हैं, लेकिन यह सच है, अगर आँख बंद करके इस्तेमाल किया जाए, तो भयानक प्रदर्शन हो सकता है।
जॉन पॉवेल

-2
WITH u AS (
    SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS account (id,name)
)
SELECT id, name, length(name) from u;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.