PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cara mengelompokkan baris berikut dengan nilai yang tidak unik

Jika kasus Anda sesederhana yang disarankan oleh nilai contoh, jawaban @Giorgos melayani dengan baik.

Namun, biasanya tidak demikian . Jika id kolom adalah serial , Anda tidak dapat mengandalkan asumsi bahwa baris dengan time sebelumnya juga memiliki id yang lebih kecil .
Juga, time nilai (atau timestamp seperti yang mungkin Anda miliki) dapat dengan mudah menjadi duplikat, Anda perlu membuat urutan pengurutan tidak ambigu.

Dengan asumsi keduanya bisa terjadi, dan Anda menginginkan id dari baris dengan time paling awal per irisan waktu (sebenarnya, yang terkecil id untuk waktu paling awal , mungkin ada ikatan), kueri ini akan menangani situasi dengan benar:

SELECT *
FROM  (
   SELECT DISTINCT ON (way, grp)
          id, way, time AS time_from
        , max(time) OVER (PARTITION BY way, grp) AS time_to
   FROM (
      SELECT *
           , row_number() OVER (ORDER BY time, id)  -- id as tie breaker
           - row_number() OVER (PARTITION BY way ORDER BY time, id) AS grp
      FROM   table1
      ) t
   ORDER  BY way, grp, time, id
   ) sub
ORDER  BY time_from, id;
  • ORDER BY time, id menjadi tidak ambigu. Dengan asumsi waktu tidak unik, tambahkan (diasumsikan unik) id untuk menghindari hasil yang sewenang-wenang - yang dapat mengubah kueri dengan cara yang licik.

  • max(time) OVER (PARTITION BY way, grp) :tanpa ORDER BY , bingkai jendela mencakup semua baris PARTITION, jadi kita mendapatkan maksimum absolut per irisan waktu.

  • Lapisan kueri luar hanya diperlukan untuk menghasilkan urutan pengurutan yang diinginkan dalam hasil, karena kita terikat pada ORDER BY yang berbeda di subkueri sub dengan menggunakan DISTINCT ON . Detail:

SQL Fiddle mendemonstrasikan kasus penggunaan.

Jika Anda ingin mengoptimalkan kinerja, fungsi plpgsql bisa lebih cepat dalam kasus seperti itu. Jawaban yang terkait erat:

Selain:jangan gunakan nama tipe dasar time sebagai pengenal (juga kata yang dicadangkan dalam SQL standar ).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. melakukan operasi terkait datetime di PHP

  2. SQLAlchemy SELECT WITH klausa/pernyataan (pgsql)

  3. Batasan Postgresql untuk memeriksa karakter non-ascii

  4. Bagaimana kita bisa membuat "statement_timeout" berfungsi di dalam suatu fungsi?

  5. Bagaimana cara mengubah struktur data jsonb yang disimpan di Postgres