PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zwróć tablicę lat jako zakresy lat

SELECT id, string_agg(year_range, ', ') AS year_ranges
FROM (
   SELECT id, CASE WHEN count(*) > 1
               THEN min(year)::text || '-' ||  max(year)::text 
               ELSE min(year)::text
              END AS year_range
   FROM  (
      SELECT *, row_number() OVER (ORDER BY id, year) - year AS grp
      FROM  (
         SELECT id, unnest(years) AS year
         FROM  (VALUES (2::int, '{1999,2000,2010,2011,2012}'::int[])
                      ,(3,      '{1990,1991,2007}')
               ) AS tbl(id, years)
         ) sub1
      ) sub2
   GROUP  BY id, grp
   ORDER  BY id, min(year)
   ) sub3
GROUP  BY id
ORDER  BY id

Produkuje dokładnie pożądany wynik.

Jeśli masz do czynienia z tablicą varchar (varchar[] , po prostu prześlij go do int[] , zanim przejdziesz dalej. Wydaje się, że jest to w pełni legalna forma:

years::int[]

Zastąp wewnętrzny podwybór nazwą tabeli źródłowej w produktywnym kodzie.

 FROM  (VALUES (2::int, '{1999,2000,2010,2011,2012}'::int[])
              ,(3,      '{1990,1991,2007}')
       ) AS tbl(id, years)

->

FROM  tbl

Ponieważ mamy do czynienia z liczbą naturalnie rosnącą (rok) możemy użyć skrótu, aby utworzyć grupy kolejnych lat (tworząc zakres). Od numeru wiersza odejmuję sam rok (uporządkowany według roku). W kolejnych latach zarówno numer wiersza, jak i rok zwiększają się o jeden i dają ten sam grp numer. W przeciwnym razie zaczyna się nowy asortyment.

Więcej o funkcjach okien w instrukcji tutaj i tutaj .

W tym przypadku funkcja plpgsql może być jeszcze szybsza. Musiałbyś przetestować. Przykłady w tych powiązanych odpowiedziach:
Uporządkowana liczba kolejnych powtórzeń/duplikatów
ROW_NUMBER() pokazuje nieoczekiwane wartości



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Używanie rekurencyjnego CTE z Ecto

  2. Wpisz ENUM w SQLAlchemy z PostgreSQL

  3. Postgresql - jedna baza danych dla wszystkich lub jedna baza danych na klienta

  4. Moje ulubione rozszerzenia PostgreSQL — część pierwsza

  5. Błąd:nieprawidłowa składnia wejściowa dla liczby całkowitej: