পোস্টগ্র্রেএসকিউএলে দুটি টেবিলের অভিন্ন সামগ্রী রয়েছে কিনা তা পরীক্ষা করা হচ্ছে


28

এটি ইতিমধ্যে স্ট্যাক ওভারফ্লোতে জিজ্ঞাসা করা হয়েছে , তবে কেবল মাইএসকিউএল-এর জন্য। আমি PostgreSQL ব্যবহার করছি। দুর্ভাগ্যক্রমে (এবং আশ্চর্যরূপে) পোস্টগ্রিসকিউএল এর মতো কিছু রয়েছে বলে মনে হয় না CHECKSUM table

একটি পোস্টগ্রিজ এসকিউএল সমাধান ভাল হবে তবে জেনেরিকটি আরও ভাল। আমি http://www.besttechtools.com/articles/article/sql-query-to-check-two-tables-have-identical-data খুঁজে পেয়েছি , তবে আমি ব্যবহৃত যুক্তি বুঝতে পারি না।

পটভূমি: আমি কিছু ডাটাবেস উত্পন্ন কোড পুনরায় লিখেছি, সুতরাং আমার পুরাতন এবং নতুন কোডটি অভিন্ন ফলাফল এনেছে কিনা তা খতিয়ে দেখা দরকার।


3
আপনি EXCEPTএই প্রশ্নটি ব্যবহার করতে পারেন : এসকিউএলে দুটি বড় ডেটা সেট তুলনা করার একটি কার্যকর উপায়
ypercubeᵀᴹ

pg_comparator দক্ষ টেবিল সামগ্রী তুলনা এবং সিঙ্ক্রোনাইজেশন করে
নাটমাকা

@ নাটকমাকাকে কি আলাদা উত্তর দেওয়া উচিত?
ফাহিম মিঠা

উত্তর:


24

একটি বিকল্প হ'ল নিম্নলিখিত ফর্মটিতে দুটি টেবিলের মধ্যে পূর্ণ আউটর জয়েন ব্যবহার করুন:

SELECT count (1)
    FROM table_a a
    FULL OUTER JOIN table_b b 
        USING (<list of columns to compare>)
    WHERE a.id IS NULL
        OR b.id IS NULL ;

উদাহরণ স্বরূপ:

CREATE TABLE a (id int, val text);
INSERT INTO a VALUES (1, 'foo'), (2, 'bar');

CREATE TABLE b (id int, val text);
INSERT INTO b VALUES (1, 'foo'), (3, 'bar');

SELECT count (1)
    FROM a
    FULL OUTER JOIN b 
        USING (id, val)
    WHERE a.id IS NULL
        OR b.id IS NULL ;

2 এর গণনা ফিরিয়ে দেবে, যদিও:

CREATE TABLE a (id int, val text);
INSERT INTO a VALUES (1, 'foo'), (2, 'bar');

CREATE TABLE b (id int, val text);
INSERT INTO b VALUES (1, 'foo'), (2, 'bar');

SELECT count (1)
    FROM a
    FULL OUTER JOIN b 
        USING (id, val)
    WHERE a.id IS NULL
        OR b.id IS NULL ;

0 গণনার জন্য প্রত্যাশাকে প্রত্যাবর্তন করে।

এই পদ্ধতিটি সম্পর্কে আমি যে জিনিসটি পছন্দ করি তা হ'ল এটি কেবলমাত্র প্রতিটি টেবিলটি একবার বনাম বনাম প্রতি সারণি দুটি বার পড়া প্রয়োজন যখন উপস্থিতি ব্যবহার করার সময়। অতিরিক্তভাবে, এটি এমন কোনও ডাটাবেসের জন্য কাজ করা উচিত যা সম্পূর্ণ বাইরের সাথে যোগ দেয় (কেবল পোস্টগ্রেস্কল নয়) supports

আমি সাধারণত ব্যবহারের ধারাটি ব্যবহারকে নিরুৎসাহিত করি তবে এখানে এমন একটি পরিস্থিতি যেখানে আমি বিশ্বাস করি এটি আরও ভাল পদ্ধতির বলে মনে হয়।

সংযোজন 2019-05-03:

যদি সম্ভাব্য নাল ডেটা নিয়ে কোনও সমস্যা থাকে, (যেমন আইডি কলামটি নয় তবে ভাল হয়) তবে আপনি নিম্নলিখিতটি চেষ্টা করতে পারেন:

SELECT count (1)
    FROM a
    FULL OUTER JOIN b
        ON ( a.id = b.id
            AND a.val IS NOT DISTINCT FROM b.val )
    WHERE a.id IS NULL
        OR b.id IS NULL ;

ভ্যাল যদি অল্প হয় তবে এটি ব্যর্থ হবে না?
অমিত গোল্ডস্টেইন

@ অ্যামিটগল্ডস্টিন - নালাগুলি একটি সমস্যা হবে। এটির সম্ভাব্য সমাধানের জন্য আমার সংযোজনটি দেখুন।
জিএসএম

30

আপনি EXCEPTঅপারেটর ব্যবহার করতে পারেন । উদাহরণস্বরূপ, যদি টেবিলগুলিতে অভিন্ন কাঠামো থাকে তবে নীচেরগুলি সমস্ত সারণী এক টেবিলে থাকবে তবে অন্যটি নয় (সুতরাং 0 টি সারি যদি সারণিতে অভিন্ন ডেটা থাকে):

(TABLE a EXCEPT TABLE b)
UNION ALL
(TABLE b EXCEPT TABLE a) ;

বা EXISTSসম্ভাব্য 2 টি ফলাফলের মধ্যে একটির সাথে কেবল একটি বুলিয়ান মান বা একটি স্ট্রিং ফিরিয়ে আনতে হবে:

SELECT CASE WHEN EXISTS (TABLE a EXCEPT TABLE b)
              OR EXISTS (TABLE b EXCEPT TABLE a)
            THEN 'different'
            ELSE 'same'
       END AS result ;

এসকিউএলফিডেলে পরীক্ষা করা হয়েছে


এছাড়াও এটি EXCEPTনকলগুলি সরিয়ে দেয় না (আপনার টেবিলগুলিতে কিছু PRIMARY KEYবা UNIQUEসীমাবদ্ধতা থাকলে উদ্বেগ হওয়া উচিত নয় তবে আপনি যদি স্বেচ্ছাসেবী প্রশ্নের সাথে তুলনা করছেন যা সম্ভবত ডুপ্লিকেট সারি তৈরি করতে পারে)।

EXCEPTকীওয়ার্ডের অন্য একটি জিনিসটি এটি NULLমানকে অভিন্ন হিসাবে বিবেচনা করে , সুতরাং যদি টেবিলের Aসাথে একটি সারি থাকে (1,2,NULL)এবং টেবিলের Bসাথে একটি সারি থাকে (1,2,NULL), তবে প্রথম কোয়েরিতে এই সারিগুলি দেখানো হবে না এবং 'same'যদি দুটি সারণীর অন্য কোনও সারি না থাকে তবে দ্বিতীয় কোয়েরিটি ফিরে আসবে ।

আপনি যদি এই জাতীয় সারি পৃথক হিসাবে গণনা করতে চান তবে FULL JOINসমস্ত (পৃথক) সারি পেতে আপনি জিএসএম এর উত্তরে বিভিন্নতা ব্যবহার করতে পারেন :

SELECT *
FROM a NATURAL FULL JOIN b
WHERE a.some_not_null_column IS NULL 
   OR b.some_not_null_column IS NULL ;

এবং একটি হ্যাঁ / কোন উত্তর পেতে:

SELECT CASE WHEN EXISTS
            ( SELECT *
              FROM a NATURAL FULL JOIN b
              WHERE a.some_not_null_column IS NULL 
                 OR b.some_not_null_column IS NULL
            )
            THEN 'different'
            ELSE 'same'
       END AS result ;

যদি দুটি টেবিলের সমস্ত কলামগুলি উত্তরযোগ্য না হয় তবে দুটি পদ্ধতির অভিন্ন উত্তর দেবে।


আরও কিছু কার্যকর পদ্ধতি থাকতে পারে, এটি নিশ্চিত নয়।
ypercubeᵀᴹ

@ ফাহিমমিথা আপনি এটির চেয়ে কম কলামগুলির তুলনা করতে ব্যবহার করতে পারেন। কেবল এর SELECT <column_list> FROM aপরিবর্তেTABLE a
ypercubeᵀᴹ

2
EXCEPTক্যোয়ারিতে একটি beaut হয়!
এরউইন ব্র্যান্ডসেটেটার

এক্সেসপিটি ক্যোয়ারী মিষ্টি!
sharadov

1

আপনার কিছু প্রয়োজন বাদে দরকার need

SELECT * FROM first_table
EXCEPT
SELECT * FROM second_table

এটি প্রথম টেবিল থেকে সমস্ত সারণী যা দ্বিতীয় সারণীতে নেই return


0

লিঙ্কযুক্ত কোডটি দেখে আপনি বুঝতে পারেন না:

select count(*) from
(
select * From EmpDtl1
union
select * From EmpDtl2
)

গোপন সস এর unionবিপরীতে ব্যবহার করছে union all। পূর্ববর্তীটি কেবল স্বতন্ত্র সারিগুলি ধরে রাখে যদিও পরবর্তীকৃতগুলি সদৃশ ( রেফারেন্স ) রাখে । অন্য কথায় নেস্টেড ক্যোয়ারী বলছে "আমাকে এমপিডিটিএল 1 থেকে সমস্ত সারি এবং কলামগুলি দিন এবং এমপিডিটিএল 2 থেকে ইতিমধ্যে যা এমপিডিটিএল 1 এ নেই সেগুলি আমাকে দিন"। এই সাবকোয়ারির গণনা এমপিডিটিএল 1 এর গণনার সমান হবে যদি এবং কেবল এমপিডিটিএল 2 ফলাফলটিতে কোনও সারি অবদান না দেয় অর্থাৎ দুটি সারণী একরকম হয়।

বিকল্পভাবে, টেক্সটগুলি দুটি পাঠ্য ফাইলগুলিতে কী অনুক্রমের মধ্যে ফেলে দিন এবং আপনার পছন্দসই তুলনা সরঞ্জামটি ব্যবহার করুন।


3
যখন কম সারি থাকে এবং সমস্ত বিদ্যমান সারি বিদ্যমান থাকে তখন EmpDtl2এটি কেসটি সনাক্ত করতে পারে না । EmpDtl1EmpDtl1
a_horse_with_no_name
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.