PostgreSQL এ ভ্যালু ব্যবহার করে কীভাবে অস্থায়ী সারণী তৈরি করতে হয়


38

আমি পোস্টগ্রেএসকিউএল শিখছি এবং WITHডিবাগিংয়ের উদ্দেশ্যে কীভাবে একটি অস্থায়ী টেবিল বা নিয়মিত টেবিলের জায়গায় ব্যবহার করা যেতে পারে এমন একটি ঘোষণাপত্র তৈরি করবেন তা নির্ধারণ করার চেষ্টা করছি ।

আমি টেবিলVALUES তৈরির জন্য ডকুমেন্টেশনের দিকে নজর দিয়েছি এবং এটি বলছে যে ক্যোয়ারী হিসাবে ব্যবহার করা যেতে পারে তবে কোনও উদাহরণ দেয় না; এর VALUESসাথে যুক্ত দফাটির নথির কোনও উদাহরণ নেই?

সুতরাং, আমি নিম্নলিখিত হিসাবে একটি সহজ পরীক্ষা লিখেছি:

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

তবে পোস্টগ্রিসকিউএল (9.3) অভিযোগ করছে

"AS" এর কাছাকাছি বা কাছাকাছি সিনট্যাক্স ত্রুটি

আমার প্রশ্নগুলি হ'ল:

  1. আমি কীভাবে উপরের বিবৃতিটি ঠিক করতে পারি?

  2. আমি এটিকে কীভাবে ব্যবহার করতে মানিয়ে নিতে পারি WITH block?

আগাম ধন্যবাদ.


আমি আরও কিছু আধুনিক পরামর্শ দিয়ে এই প্রশ্নের উত্তর দেওয়ার চেষ্টা করেছি (যেমন নির্বাচিত উত্তরটি অবহিত
ইভান ক্যারল

উত্তর:


46

সম্পাদনা: আমি আসল স্বীকৃত উত্তরটি ঠিক তেমনই রেখে দিচ্ছি, তবে দয়া করে নোট করুন যে নীচের সম্পাদনাটি, যেমন__হর্স_উইথ_নো_নাম দ্বারা প্রস্তাবিত, ভ্যালু ব্যবহার করে একটি অস্থায়ী টেবিল তৈরি করার জন্য পছন্দসই পদ্ধতি।

আপনি যদি কেবল কোনও সারণী তৈরি এবং এটিতে thanোকানোর পরিবর্তে কিছু মান থেকে নির্বাচন করতে চান তবে আপনি এর মতো কিছু করতে পারেন:

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;

সম্পাদনা: 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 দ্বারা করা মন্তব্যগুলি এবং ওপির মূল প্রশ্নে এটিতে মান তালিকার সঠিক ডেটাটাইপগুলিতে একটি কাস্ট অন্তর্ভুক্ত রয়েছে এবং এটি একটি সিটিই (ডাব্লুআইটি) বিবৃতি ব্যবহার করে।

এছাড়াও, ইভান ক্যারোলের উত্তরে নির্দেশিত হিসাবে, একটি সিটিই কোয়েরিটি একটি অপ্টিমাইজেশন বেড়া , অর্থাৎ, সিটিই সর্বদা বাস্তবায়িত হয়। সিটিই ব্যবহারের জন্য অনেকগুলি ভাল কারণ রয়েছে, তবে সাবধানতার সাথে ব্যবহার না করা হলে যথেষ্ট উল্লেখযোগ্য পারফরম্যান্স হিট হতে পারে। তবে অনেকগুলি উদাহরণ রয়েছে যেখানে অপ্টিমাইজেশনের বেড়াটি কার্য সম্পাদনকে বাড়িয়ে তুলতে পারে, তাই অন্ধভাবে এড়াতে না পারার বিষয়টি সচেতন থাকার মতো।


12
দস্তাবেজগুলি থেকে : " টেবিল তৈরি করুন
কার্যত

অপ্টিমাইজেশন বেড়া অগত্যা খারাপ জিনিস নয় thing আমি অনেক বিবৃতি দেখেছি যে আমি যে কারণে দ্রুততরভাবে চালানোর জন্য সুর করতে পারি।
a_horse_with_no_name

অবশ্যই, আমি এটিও স্পষ্ট করে দিয়েছি। আমি স্থানীয় সময়কালে সিটিই ব্যবহার করি। আপনার যদি এমন কিছু রয়েছে WHERE ST_Intersects(geom, (SELECT geom FROM sometable)বা WHERE ST_Intersects(geom, ST_Buffer(anothergeom, 10)তার মতো ক্লাসের ক্লজ থাকে তবে প্রায়শই ক্যোয়ারী পরিকল্পনাকারীর স্থানিক সূচি ব্যবহার করা হয় না কারণ জিম কলামটি আর ব্যস্ত থাকে না। আপনি যদি প্রাথমিক সিটিইতে আপনার আগ্রহের ক্ষেত্র তৈরি করেন তবে এই সমস্যাটি চলে যায়। এটি খুব সুবিধাজনক, যদি আপনি একই ক্যোয়ারির আরও একাধিক অভিব্যক্তিতে একই আইওই ব্যবহার করতে চান তবে এটি কোনও জিআইএস প্রসঙ্গে অস্বাভাবিক নয়।
জন পাওয়েল

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);

আপনি সিটিই ব্যবহার করতে এটি আবারও লিখতে পারেন:

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) ;

আপনি প্রথম সারির মান ingালাই করে প্রকারগুলি সংজ্ঞায়িত করতে পারেন:

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ᵀᴹ

হ্যাঁ, তবে অন্য সম্পর্কের সাথে যোগ না দেওয়ার জন্য কেন আপনাকে কয়েকটি স্থির লুকের মান সহ একটি অস্থায়ী টেবিলের প্রয়োজন হবে? প্রশ্নটি কীভাবে বর্ণিত হোক না কেন এই সমাধানটি সমস্যার সমাধান করে ves
ইস্পির

1
হয়তো ওপি কেবল এমন কিছু উদাহরণের উদয় করতে ঘটেছে যা প্রশ্ন হিসাবে পোস্ট করা সহজ হবে, তবে আসল তথ্যটিতে হাজার হাজার মান আছে?
stannius

ওপি বিশেষত মানগুলি ব্যবহার করে বলেছে যাতে আমার উত্তর এখনও প্রয়োগ হয় ঠিক যেমনটি এটি করে
ইস্পির

2

প্রথমে সর্বদা মানকযুক্ত ব্যবহার করুন CREATE TABLE AS, SELECT INTOযেমন অন্য উত্তরে প্রস্তাবিত হয়েছে এক দশক ধরে অবহেলিত বাক্য গঠন। আপনি একটি সিটিই দিয়ে ব্যবহার করতে পারেনCREATE TABLE AS

যদিও এখানে অনেক উত্তর একটি সিটিই ব্যবহার করার পরামর্শ দিচ্ছে, এটি পছন্দসই নয়। আসলে, এটি সম্ভবত কিছুটা ধীর। এটি কেবল একটি টেবিলের মতো গুটিয়ে রাখুন।

DROP TABLE IF EXISTS lookup;

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

যদি আপনাকে অবশ্যই একটি নির্বাচিত বিবৃতি লিখতে হয় তবে আপনি এটিও করতে পারেন (এবং আপনার কোনও সিটিই লাগবে না)।

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

পোস্টগ্রিজ এসকিউএলএর একটি সিটিই বস্তুগতকরণকে বাধ্য করে। এটি একটি অপ্টিমাইজেশন বেড়া। সেই কারণে, সাধারণত আপনি যখন ব্যয়গুলি বুঝতে পারছেন এবং পারফরম্যান্স উন্নতি করতে জানেন তখন ব্যতীত এগুলি অন্য কোথাও ব্যবহার করা ভাল ধারণা নয়। আপনি এখানে ধীরগতি দেখতে পাবেন, উদাহরণস্বরূপ,

\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

আমি মানটি প্রতিফলিত করার জন্য উত্তরটি আপডেট করেছি এবং কীভাবে গৃহীত উত্তরটি সর্বদা সারণী তৈরির সমতুল্য হয় না তা উল্লেখ করে এবং অপ্টিমাইজেশনের বেড়াতে একটি মন্তব্য যুক্ত করেছি, যা সামনে আনার জন্য খুব ভাল বিষয় point সিটিইগুলি এতগুলি সুবিধা নিয়ে আসে তবে এটি সত্য, যদি অন্ধভাবে ব্যবহার করা হয় তবে ভয়াবহ পারফরম্যান্সের দিকে নিয়ে যেতে পারে।
জন পাওয়েল

-2
WITH u AS (
    SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS account (id,name)
)
SELECT id, name, length(name) from u;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.