سؤال

لدي طاولة وأرغب في سحب صف واحد لكل معرف مع تسلسل قيم الحقل.

في طاولتي ، على سبيل المثال ، لدي هذا:

TM67 | 4  | 32556
TM67 | 9  | 98200
TM67 | 72 | 22300
TM99 | 2  | 23009
TM99 | 3  | 11200

وأود الإخراج:

TM67 | 4,9,72 | 32556,98200,22300
TM99 | 2,3    | 23009,11200

في MySQL تمكنت من استخدام الوظيفة الإجمالية GROUP_CONCAT, ، لكن هذا لا يبدو أنه يعمل هنا ... هل هناك ما يعادل PostgreSQL ، أو طريقة أخرى لإنجاز هذا؟

هل كانت مفيدة؟

المحلول

ربما تكون هذه نقطة انطلاق جيدة (الإصدار 8.4+ فقط):

SELECT id_field, array_agg(value_field1), array_agg(value_field2)
FROM data_table
GROUP BY id_field

array_agg إرجاع صفيف ، ولكن يمكنك إلقاء هذا النص وتحريره حسب الحاجة (انظر التوضيحات ، أدناه).

قبل الإصدار 8.4 ، عليك تحديده بنفسك قبل الاستخدام:

CREATE AGGREGATE array_agg (anyelement)
(
    sfunc = array_append,
    stype = anyarray,
    initcond = '{}'
);

(أعيد صياغته من وثائق PostgreSQL)

توضيحات:

  • نتيجة صب صفيف للنص هي أن السلسلة الناتجة تبدأ وتنتهي بأقواس مجعد. تحتاج تلك الأقواس إلى إزالتها بواسطة بعض الطرق ، إذا لم تكن مرغوبة.
  • إن إلقاء نص على النص على نص أفضل محاكاة إخراج CSV كعناصر تحتوي على فواصل مضمنة مزدوجة في الإخراج بأسلوب CSV القياسي. لا array_to_string () أو string_agg () (وظيفة "group_concat" تمت إضافتها في 9.1) اقتبس من السلاسل مع فواصل مضمنة ، مما يؤدي إلى عدد غير صحيح من العناصر في القائمة الناتجة.
  • لا تلمي وظيفة 9.1 string_agg () الجديدة النتائج الداخلية للنص أولاً. لذا ، فإن "string_agg (value_field)" من شأنه أن ينشئ خطأ إذا كان Value_field صحيحًا. "string_agg (value_field :: text)" سيكون مطلوبًا. تتطلب طريقة ARRAY_AGG () واحدة فقط بعد التجميع (بدلاً من يلقي لكل قيمة).

نصائح أخرى

منذ 9.0 هذا أسهل:

SELECT id, 
       string_agg(some_column, ',')
FROM the_table
GROUP BY id
SELECT array_to_string(array(SELECT a FROM b),', ');

سوف تفعل كذلك.

حاول مثل هذا:

select field1, array_to_string(array_agg(field2), ',')
from table1
group by field1;

والنسخة للعمل على نوع الصفيف:

select
  array_to_string(
    array(select distinct unnest(zip_codes) from table),
    ', '
);

بلدي sugestion في postgresql

SELECT cpf || ';' || nome || ';' || telefone  
FROM (
      SELECT cpf
            ,nome
            ,STRING_AGG(CONCAT_WS( ';' , DDD_1, TELEFONE_1),';') AS telefone 
      FROM (
            SELECT DISTINCT * 
            FROM temp_bd 
            ORDER BY cpf DESC ) AS y
      GROUP BY 1,2 ) AS x   
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top