দুটি ইভেন্ট ইভেন্ট টেবিল একক সময়রেখায় একত্রিত করুন


12

দুটি টেবিল দেওয়া হয়েছে:

CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);

আমি একটি ক্যোয়ারী যে জন্য আয় মান লিখতে ইচ্ছুক ts, fooএবং barযে সাম্প্রতিকতম মূল্যবোধের একটি ইউনিফাইড দৃশ্য প্রতিনিধিত্ব করে। অন্য কথায়, যদি fooএতে থাকে:

ts | foo
--------
1  | A
7  | B

এবং এতে barরয়েছে:

ts | bar
--------
3  | C
5  | D
9  | E

আমি ফিরে আসা একটি প্রশ্ন চাই:

ts | foo | bar
--------------
1  | A   | null
3  | A   | C
5  | A   | D
7  | B   | D
9  | B   | E

যদি উভয় টেবিলের একই সময়ে ইভেন্ট থাকে তবে অর্ডারটি কোনও বিষয় নয়।

আমি ইউনিয়ন সমস্ত এবং ডামি মান ব্যবহার করে প্রয়োজনীয় কাঠামো তৈরি করতে সক্ষম হয়েছি:

SELECT ts, foo, null as bar FROM foo
UNION ALL SELECT ts, null as foo, bar FROM bar

যা আমাকে নতুন মানগুলির একটি রৈখিক টাইমলাইন দেবে, তবে পূর্ববর্তী সারিগুলির উপর ভিত্তি করে নাল মানগুলি কীভাবে পপ করা যায় তা আমি কার্যকরভাবে কাজ করতে সক্ষম নই। আমি lagউইন্ডোটির কার্যকারিতাটি চেষ্টা করে দেখেছি , তবে আফিকাল এটি কেবল আগের সারিতেই দেখবে, পুনরাবৃত্তভাবে পিছিয়ে থাকবে না। আমি রিকার্সিভ সিটিইতে দেখেছি, তবে কীভাবে শুরু এবং সমাপ্তির শর্তগুলি সেট আপ করতে হয় তা সম্পর্কে আমি নিশ্চিত নই।


সময়ের সাথে মানগুলি fooএবং barকঠোরভাবে আরোহণ হয় বা পরীক্ষার কেস কি এই ক্ষেত্রে বিভ্রান্তিকর হয়?
এরউইন ব্র্যান্ডসটেটার

2
অন্য কারও ঝামেলা বাঁচাতে sqlfiddle.com/#!15/511414
ক্রেগ

1
উত্তর দেওয়ার পরে প্রশ্নের প্রকৃতি পরিবর্তন করার পরিবর্তে দয়া করে একটি নতুন প্রশ্ন জিজ্ঞাসা করুন । আপনি রেফারেন্সের জন্য সর্বদা এটির সাথে লিঙ্ক করতে পারেন। (আপনার কাছে একটি উত্তর থাকলে আপনি নিজের উত্তরও সরবরাহ করতে পারেন)) মূল সংস্করণটি সাধারণ মানুষের কাছে আকর্ষণীয় হওয়া উচিত। আসুন একটি প্রশ্নে অনেক কিছু প্যাক না।
এরউইন ব্র্যান্ডসটেটার

ওভারলোডের জন্য দুঃখিত আমি অনুসরণটি সরিয়ে দিয়েছি এবং এটি একটি নতুন প্রশ্ন হিসাবে যুক্ত করেছি ।
ক্রিস্টোফার কুরি

উত্তর:


7

FULL [OUTER] JOINদুটি রাউন্ড উইন্ডো ফাংশনগুলির সাথে মিলিত একটি ব্যবহার করুন :

SELECT ts
     , min(foo) OVER (PARTITION BY foo_grp) AS foo
     , min(bar) OVER (PARTITION BY bar_grp) AS bar
FROM (
   SELECT ts, f.foo, b.bar
        , count(f.foo) OVER (ORDER BY ts) AS foo_grp
        , count(b.bar) OVER (ORDER BY ts) AS bar_grp
   FROM   foo f
   FULL   JOIN bar b USING (ts)
   ) sub;

যেহেতু count()NULL মান গণনা করে না এটি কেবল প্রতিটি নন-মান দিয়ে স্বাচ্ছন্দ্যে বৃদ্ধি পায়, এর ফলে এমন গ্রুপ তৈরি হয় যা একই মান ভাগ করে নেবে। বাহ্যিক ক্ষেত্রে SELECT, min()(বা max()) তেমনিভাবে ন্যূনাল মানগুলিকে উপেক্ষা করে, যার দ্বারা প্রতি গ্রুপে এক-নাল মানকে বাছাই করে। Voila।

সম্পর্কিত FULL JOINকেস:

এটি এমন একটি ক্ষেত্রে যেখানে একটি পদ্ধতিগত সমাধানটি দ্রুততর হতে পারে, যেহেতু এটি একক স্ক্যানে কাজটি সম্পন্ন করতে পারে। এই plpgsql ফাংশনটি পছন্দ করুন :

CREATE OR REPLACE FUNCTION f_merge_foobar()
  RETURNS TABLE(ts int, foo text, bar text) AS
$func$
#variable_conflict use_column
DECLARE
   last_foo text;
   last_bar text;
BEGIN
   FOR ts, foo, bar IN
      SELECT ts, f.foo, b.bar
      FROM   foo f
      FULL   JOIN bar b USING (ts)
      ORDER  BY 1
   LOOP
      IF foo IS NULL THEN foo := last_foo;
      ELSE                last_foo := foo;
      END IF;

      IF bar IS NULL THEN bar := last_bar;
      ELSE                last_bar := bar;
      END IF;

      RETURN NEXT;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

কল করুন:

SELECT * FROM f_merge_foobar();

ডিবি <> দু'জনে এখানে প্রদর্শন করুন iddle

সম্পর্কিত উত্তর ব্যাখ্যা করে #variable_conflict use_column:


আকর্ষণীয় সমস্যা তাই না। আমি মনে করি একটি দক্ষ সমাধান সম্ভবত একটি coalesceউইন্ডো ফাংশন তৈরি প্রয়োজন ।
ক্রেগ রিঞ্জার

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

@ ক্রিস্টোফার: আমি আপনার সেটআপের প্রতিটি ভেরিয়েন্টের অভিনয়ে আগ্রহী। EXPLAIN ANALYZE, সেরা 5 ...?
এরউইন ব্র্যান্ডসটেটার

2
করুণা যে পোস্টগ্র্রেস এখনও কার্যকর করেনি IGNORE NULLS(যেমন ওরাকল রয়েছে: sqlfiddle.com/#!4/fab35/1 )।
ypercubeᵀᴹ

1
@ টিউবারকিউ: হ্যাঁ, ওরাকল সরল কোনওভাবেই নুল মান সংরক্ষণ করে না এবং ফলস্বরূপ ''এবং NULL এর মধ্যে পার্থক্য বলতে পারে না ।
এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.