পোস্টগ্রাগিতে সদৃশ অ্যারের মানগুলি নির্মূল করুন


87

আমার ধরণের অ্যারে রয়েছে bigint, আমি কীভাবে সেই অ্যারেতে সদৃশ মানগুলি সরিয়ে ফেলব?

প্রাক্তন: array[1234, 5343, 6353, 1234, 1234]

আমার পাওয়া উচিত array[1234, 5343, 6353, ...]

SELECT uniq(sort('{1,2,3,2,1}'::int[]))পোস্টগ্রিস ম্যানুয়ালটিতে আমি উদাহরণটি পরীক্ষা করেছি তবে এটি কার্যকর হচ্ছে না।

উত্তর:


94

আমি একই মুখোমুখি। তবে আমার ক্ষেত্রে একটি অ্যারে array_aggফাংশনের মাধ্যমে তৈরি করা হয়েছে । এবং ভাগ্যক্রমে এটি DISTINCT মানগুলিকে একত্রিত করতে দেয় , যেমন:

  array_agg(DISTINCT value)

এটি আমার পক্ষে কাজ করে।


4
নোট করুন যে DISTINCT উইন্ডো ফাংশনের জন্য সমর্থিত নয়।
ভাবা যায়

trim(string_agg(distinct to_char(z.dat_codigo,'0000000000'),'')) as dat_codigo,
tks

4
অ্যারে_অ্যাগ নির্বাচন করুন (DISTINCT অ্যারে [1,2,2,3]) "{{1,2,2,3}}"
ব্যবহারকারীর 48956

@ ব্যবহারকারী 48956, এটি যৌক্তিক, আপনি মান হিসাবে একটি অ্যারে প্রবেশ করার সাথে সাথে, আপনাকে প্রশ্নের একক হিসাবে কলাম অনুসারে শ্রেণিবদ্ধ করা হয়েছে এমন একক কলাম সেট করতে হবে
ড্যানিয়েল টিউল্প

83

sort(int[])এবং uniq(int[])ফাংশন দ্বারা উপলব্ধ করা হয় intarray contrib মডিউল।

এর ব্যবহার সক্ষম করতে, আপনাকে অবশ্যই মডিউলটি ইনস্টল করতে হবে ।

আপনি যদি ইনটারে অবদান মডিউলটি ব্যবহার করতে না চান, বা যদি আপনাকে বিভিন্ন ধরণের অ্যারে থেকে নকলগুলি সরাতে হয় তবে আপনার অন্য দুটি উপায় রয়েছে।

আপনার যদি কমপক্ষে PostgreSQL 8.4 থাকে তবে আপনি unnest(anyarray)কার্যকারিতাটি গ্রহণ করতে পারেন

SELECT ARRAY(SELECT DISTINCT UNNEST('{1,2,3,2,1}'::int[]) ORDER BY 1);
 ?column? 
----------
 {1,2,3}
(1 row)

বিকল্পভাবে আপনি এটি করতে নিজের ফাংশন তৈরি করতে পারেন

CREATE OR REPLACE FUNCTION array_sort_unique (ANYARRAY) RETURNS ANYARRAY
LANGUAGE SQL
AS $body$
  SELECT ARRAY(
    SELECT DISTINCT $1[s.i]
    FROM generate_series(array_lower($1,1), array_upper($1,1)) AS s(i)
    ORDER BY 1
  );
$body$;

এখানে একটি নমুনা প্রার্থনা:

SELECT array_sort_unique('{1,2,3,2,1}'::int[]);
 array_sort_unique 
-------------------
 {1,2,3}
(1 row)

4
সমস্যার সমাধান ("সদৃশ অ্যারে মানগুলি অপসারণ করুন") বাছাই করার দরকার নেই । যদিও সাধারণত একটি দরকারী বৈশিষ্ট্য হয় তবে এ প্রসঙ্গে / প্রয়োজনে এটি অপ্রয়োজনীয় (সিপিইউ ব্যয়)।
পিটার ক্রাউস

27

... এই ধরণের অ্যারে_ এক্স ইউটিলিটির জন্য স্ট্যাট্যান্ডার্ড লাইব্রেরি (?) কোথায় ?

অনুসন্ধান করার চেষ্টা করুন ... কিছু দেখুন তবে কোনও মান নেই:


সবচেয়ে সহজ এবং দ্রুত array_distinct()স্নিপেট-লিব ফাংশন

এখানে সহজ এবং সম্ভবত দ্রুত বাস্তবায়ন array_unique()বা এর জন্য array_distinct():

CREATE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$
  SELECT array_agg(DISTINCT x) FROM unnest($1) t(x);
$f$ LANGUAGE SQL IMMUTABLE;

দ্রষ্টব্য: এটি অ্যারের অ্যারে ব্যতীত অন্য কোনও ডেটাটাইপের সাথে প্রত্যাশা অনুযায়ী কাজ করে,

SELECT  array_distinct( array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99] ), 
        array_distinct( array['3','3','hello','hello','bye'] ), 
        array_distinct( array[array[3,3],array[3,3],array[3,3],array[5,6]] );
 -- "{1,2,3,4,6,8,99}",  "{3,bye,hello}",  "{3,5,6}"

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

পিএস: জেএসওএনবি অ্যারেগুলির সাথে দুর্দান্ত কাজ করে,

SELECT array_distinct( array['[3,3]'::JSONB, '[3,3]'::JSONB, '[5,6]'::JSONB] );
 -- "{"[3, 3]","[5, 6]"}"

সম্পাদনা করুন: আরও জটিল তবে দরকারী, একটি "ড্রপ নালস" পরামিতি

CREATE FUNCTION array_distinct(
      anyarray, -- input array 
      boolean DEFAULT false -- flag to ignore nulls
) RETURNS anyarray AS $f$
      SELECT array_agg(DISTINCT x) 
      FROM unnest($1) t(x) 
      WHERE CASE WHEN $2 THEN x IS NOT NULL ELSE true END;
$f$ LANGUAGE SQL IMMUTABLE;

আপনি কী দয়া করে ব্যাখ্যা করতে পারবেন যে (এক্স) কীভাবে অদ্ভুত ($ 1) টি (এক্স) এ করছে ... এছাড়াও আমি কীভাবে তারা
itemsোকানো

@ abhirathore2006 এই উত্তরটি একটি উইকি, আপনি যে ব্যাখ্যা ব্যাখ্যা করেছিলেন সেগুলি লিখতে পারেন। "অর্ডার রাখুন" সম্পর্কে, না, এটি একটি ধ্বংসাত্মক সমাধান, মূল অ্যারের ক্রম সংরক্ষণের জন্য এই পৃষ্ঠায় PLpgSQL সমাধান দেখুন। এটি দু'টি প্রয়োজনীয়তা, সাজানো এবং স্বতন্ত্র (কম মূল উত্তরটি এখানে এবং আমার মন্তব্যটি দেখুন) comm
পিটার ক্রাউস

কোনও উদ্বেগ নেই, আমি ইতিমধ্যে অন্য কোথাও থেকে সমাধানটি খুঁজে পেয়েছি, হ্যাঁ এটিই পিএলএসকিএল সমাধান
অভিরথোরে ২০০6

13

পোস্টগ্র্রেএসকিউএলএর অ্যারে হ্যান্ডলিংয়ের অভাবের বিরুদ্ধে লড়াই করার জন্য আমি সঞ্চিত পদ্ধতিগুলির একটি সেট একত্রিত করেছি anyarray। এই ফাংশনগুলি কোনও অ্যারের ডেটা-টাইপ জুড়ে কাজ করার জন্য ডিজাইন করা হয়েছে, কেবল ইনটারের মতো পূর্ণসংখ্যা নয়: https://www.github.com/JDBurnZ/anyarray

আপনার ক্ষেত্রে, আপনার যা যা প্রয়োজন তা হ'ল anyarray_uniq.sql। পোস্টগ্র্রেএসকিউএল কোয়েরিতে সেই ফাইলের বিষয়বস্তু অনুলিপি করুন এবং আটকান এবং ফাংশনটি যুক্ত করতে এটি সম্পাদন করুন। আপনার পাশাপাশি অ্যারে বাছাই করা দরকার হলে যুক্ত করুন anyarray_sort.sql

সেখান থেকে, আপনি নীচে একটি সাধারণ ক্যোয়ারী তৈরি করতে পারেন:

SELECT ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234])

এর মতো কিছু ফেরত দেয়: ARRAY[1234, 6353, 5343]

বা আপনার যদি বাছাইয়ের প্রয়োজন হয়:

SELECT ANYARRAY_SORT(ANYARRAY_UNIQ(ARRAY[1234,5343,6353,1234,1234]))

ঠিক ফিরে আসুন: ARRAY[1234, 5343, 6353]


13

DISTINCTসুস্পষ্টভাবে ব্যবহার করে অ্যারে বাছাই করে। যদি আপেক্ষিক অর্ডার অ্যারে উপাদানের যখন সদৃশ অপসারণ, ফাংশন নিচের মত ডিজাইন করা যায় সংরক্ষিত করা প্রয়োজন: (9.4 থেকে অগ্রে কাজ করা উচিত)

CREATE OR REPLACE FUNCTION array_uniq_stable(anyarray) RETURNS anyarray AS
$body$
SELECT
    array_agg(distinct_value ORDER BY first_index)
FROM 
    (SELECT
        value AS distinct_value, 
        min(index) AS first_index 
    FROM 
        unnest($1) WITH ORDINALITY AS input(value, index)
    GROUP BY
        value
    ) AS unique_input
;
$body$
LANGUAGE 'sql' IMMUTABLE STRICT;


9

এখানে "ইনলাইন" উপায়:

SELECT 1 AS anycolumn, (
  SELECT array_agg(c1)
  FROM (
    SELECT DISTINCT c1
    FROM (
      SELECT unnest(ARRAY[1234,5343,6353,1234,1234]) AS c1
    ) AS t1
  ) AS t2
) AS the_array;

প্রথমে আমরা অ্যারে থেকে একটি সেট তৈরি করি, তারপরে আমরা কেবলমাত্র স্বতন্ত্র এন্ট্রি নির্বাচন করি এবং তারপরে এটিকে আবার অ্যারেতে সমষ্টি করি।


9
বা "আরও ইনলাইন" ;-) SELECT array_agg(DISTINCT c1) FROM unnest(ARRAY[1234,5343,6353,1234,1234]) t(c1)
পিটার ক্রাউস


3

এখনও আমার মতো লোকদের যারা এখনও পোস্টগ্রিস ৮.২ নিয়ে কাজ করতে হয়, এই পুনরাবৃত্ত ফাংশন অ্যারের বাছাইয়ের কোনও পরিবর্তন না করেই সদৃশগুলি মুছে ফেলতে পারে

CREATE OR REPLACE FUNCTION my_array_uniq(bigint[])
  RETURNS bigint[] AS
$BODY$
DECLARE
    n integer;
BEGIN

    -- number of elements in the array
    n = replace(split_part(array_dims($1),':',2),']','')::int;

    IF n > 1 THEN
        -- test if the last item belongs to the rest of the array
        IF ($1)[1:n-1] @> ($1)[n:n] THEN
            -- returns the result of the same function on the rest of the array
            return my_array_uniq($1[1:n-1]);
        ELSE
            -- returns the result of the same function on the rest of the array plus the last element               
            return my_array_uniq($1[1:n-1]) || $1[n:n];
        END IF;
    ELSE
        -- if array has only one item, returns the array
        return $1;
    END IF;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;

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

select my_array_uniq(array[3,3,8,2,6,6,2,3,4,1,1,6,2,2,3,99]);

দিতে হবে

{3,8,2,6,4,1,99}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.