Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Bucketizing data tanggal dan waktu

Bucketizing data tanggal dan waktu melibatkan pengorganisasian data dalam kelompok yang mewakili interval waktu tetap untuk tujuan analitis. Seringkali inputnya adalah data deret waktu yang disimpan dalam tabel di mana baris mewakili pengukuran yang dilakukan pada interval waktu reguler. Misalnya, pengukuran dapat berupa pembacaan suhu dan kelembaban yang dilakukan setiap 5 menit, dan Anda ingin mengelompokkan data menggunakan ember per jam dan menghitung agregat seperti rata-rata per jam. Meskipun data deret waktu adalah sumber umum untuk analisis berbasis ember, konsepnya sama relevannya dengan data apa pun yang melibatkan atribut tanggal dan waktu serta ukuran terkait. Misalnya, Anda mungkin ingin mengatur data penjualan dalam keranjang tahun fiskal dan menghitung agregat seperti total nilai penjualan per tahun fiskal. Pada artikel ini, saya membahas dua metode untuk mengelompokkan data tanggal dan waktu. Salah satunya menggunakan fungsi yang disebut DATE_BUCKET, yang pada saat penulisan ini hanya tersedia di Azure SQL Edge. Cara lainnya adalah menggunakan penghitungan kustom yang mengemulasi fungsi DATE_BUCKET, yang dapat Anda gunakan dalam versi, edisi, dan ragam apa pun dari SQL Server dan Azure SQL Database.

Dalam contoh saya, saya akan menggunakan database sampel TSQLV5. Anda dapat menemukan skrip yang membuat dan mengisi TSQLV5 di sini dan diagram ER-nya di sini.

DATE_BUCKET

Seperti yang disebutkan, fungsi DATE_BUCKET saat ini hanya tersedia di Azure SQL Edge. SQL Server Management Studio sudah memiliki dukungan IntelliSense, seperti yang ditunjukkan pada Gambar 1:

Gambar 1:Dukungan kecerdasan untuk DATE_BUCKET di SSMS

Sintaks fungsinya adalah sebagai berikut:

DATE_BUCKET ( , , [, ] )

Masukan asal mewakili titik jangkar pada panah waktu. Itu bisa dari salah satu tipe data tanggal dan waktu yang didukung. Jika tidak ditentukan, defaultnya adalah 1900, 1 Januari, tengah malam. Anda kemudian dapat membayangkan garis waktu dibagi menjadi interval diskrit yang dimulai dengan titik asal, di mana panjang setiap interval didasarkan pada lebar bucket input dan bagian tanggal . Yang pertama adalah kuantitas dan yang terakhir adalah satuannya. Misalnya, untuk mengatur garis waktu dalam unit 2 bulan, Anda akan menentukan 2 sebagai lebar bucket masukan dan bulan sebagai bagian tanggal masukan.

Masukan stempel waktu adalah titik waktu sewenang-wenang yang perlu dikaitkan dengan ember yang berisi. Tipe datanya harus cocok dengan tipe data input asal . Masukan stempel waktu adalah nilai tanggal dan waktu yang terkait dengan pengukuran yang Anda ambil.

Output dari fungsi tersebut kemudian menjadi titik awal dari bucket yang berisi. Tipe data dari output adalah input timestamp .

Jika belum jelas, biasanya Anda akan menggunakan fungsi DATE_BUCKET sebagai elemen kumpulan pengelompokan dalam klausa GROUP BY kueri dan secara alami mengembalikannya ke daftar SELECT juga, bersama dengan ukuran agregat.

Masih agak bingung dengan fungsi, input, dan outputnya? Mungkin contoh spesifik dengan penggambaran visual dari logika fungsi akan membantu. Saya akan mulai dengan contoh yang menggunakan variabel input dan kemudian dalam artikel ini menunjukkan cara yang lebih umum Anda akan menggunakannya sebagai bagian dari kueri terhadap tabel input.

Perhatikan contoh berikut:

DECLARE 
  @timestamp   AS DATETIME2 = '20210510 06:30:00',
  @bucketwidth AS INT = 2,
  @origin      AS DATETIME2 = '20210115 00:00:00';
 
SELECT DATE_BUCKET(month, @bucketwidth, @timestamp, @origin);

Anda dapat menemukan penggambaran visual dari logika fungsi pada Gambar 2.

Gambar 2:Penggambaran visual logika fungsi DATE_BUCKET

Seperti yang Anda lihat pada Gambar 2, titik asal adalah nilai DATETIME2 15 Januari 2021, tengah malam. Jika titik asal ini tampak agak aneh, Anda akan benar dalam merasakan secara intuitif bahwa biasanya Anda akan menggunakan yang lebih alami seperti awal tahun, atau awal suatu hari. Bahkan, Anda sering puas dengan default, yang seingat Anda adalah 1 Januari 1900 di tengah malam. Saya sengaja ingin menggunakan titik asal yang tidak terlalu sepele untuk dapat mendiskusikan kerumitan tertentu yang mungkin tidak relevan saat menggunakan yang lebih alami. Lebih lanjut tentang ini segera.

Garis waktu kemudian dibagi menjadi interval 2 bulan diskrit dimulai dengan titik asal. Stempel waktu masukan adalah nilai DATETIME2 10 Mei 2021, 06.30.

Perhatikan bahwa stempel waktu masukan adalah bagian dari ember yang dimulai pada 15 Maret 2021, tengah malam. Memang, fungsi mengembalikan nilai ini sebagai nilai yang diketik DATETIME2:

---------------------------
2021-03-15 00:00:00.0000000

Meniru DATE_BUCKET

Kecuali Anda menggunakan Azure SQL Edge, jika Anda ingin mengelompokkan data tanggal dan waktu, untuk saat ini Anda perlu membuat solusi kustom Anda sendiri untuk meniru fungsi DATE_BUCKET. Melakukannya tidak terlalu rumit, tetapi juga tidak terlalu sederhana. Berurusan dengan data tanggal dan waktu sering kali melibatkan logika rumit dan jebakan yang perlu Anda waspadai.

Saya akan membuat perhitungan dalam langkah-langkah dan menggunakan input yang sama yang saya gunakan dengan contoh DATE_BUCKET yang saya tunjukkan sebelumnya:

DECLARE 
  @timestamp   AS DATETIME2 = '20210510 06:30:00',
  @bucketwidth AS INT = 2,
  @origin      AS DATETIME2 = '20210115 00:00:00';

Pastikan Anda menyertakan bagian ini sebelum setiap contoh kode yang akan saya tunjukkan jika Anda benar-benar ingin menjalankan kode.

Pada Langkah 1, Anda menggunakan fungsi DATEDIFF untuk menghitung perbedaan bagian tanggal unit antara asal dan stempel waktu . Saya akan menyebut perbedaan ini sebagai diff1 . Ini dilakukan dengan kode berikut:

SELECT DATEDIFF(month, @origin, @timestamp) AS diff1;

Dengan input sampel kami, ekspresi ini mengembalikan 4.

Bagian yang sulit di sini adalah Anda perlu menghitung berapa banyak seluruh unit bagian tanggal ada di antara asal dan stempel waktu . Dengan input sampel kami, ada 3 bulan penuh antara keduanya dan bukan 4. Alasan fungsi DATEDIFF melaporkan 4 adalah bahwa, ketika menghitung perbedaan, ia hanya melihat bagian input yang diminta dan bagian yang lebih tinggi tetapi bukan bagian yang lebih rendah . Jadi, ketika Anda menanyakan perbedaan bulan, fungsi tersebut hanya peduli pada bagian tahun dan bulan dari input dan bukan tentang bagian di bawah bulan (hari, jam, menit, detik, dll.). Memang, ada 4 bulan antara Januari 2021 dan Mei 2021, namun hanya 3 bulan penuh antara input penuh.

Tujuan dari Langkah 2 adalah untuk menghitung berapa banyak seluruh unit bagian tanggal ada di antara asal dan stempel waktu . Saya akan menyebut perbedaan ini sebagai diff2 . Untuk mencapai ini, Anda dapat menambahkan diff1 unit bagian tanggal ke asal . Jika hasilnya lebih besar dari stempel waktu , Anda mengurangi 1 dari diff1 untuk menghitung diff2 , jika tidak, kurangi 0 dan gunakan diff1 sebagai diff2 . Ini dapat dilakukan dengan menggunakan ekspresi CASE, seperti:

SELECT
  DATEDIFF(month, @origin, @timestamp)
    - CASE
        WHEN DATEADD(
               month, 
               DATEDIFF(month, @origin, @timestamp), 
               @origin) > @timestamp 
          THEN 1
        ELSE 0
      END AS diff2;

Ekspresi ini mengembalikan 3, yang merupakan jumlah bulan penuh antara dua input.

Ingatlah bahwa sebelumnya saya menyebutkan bahwa dalam contoh saya, saya sengaja menggunakan titik asal yang tidak alami seperti putaran awal periode sehingga saya dapat mendiskusikan kerumitan tertentu yang kemudian mungkin relevan. Misalnya, jika Anda menggunakan bulan sebagai bagian tanggal, dan awal yang tepat dari beberapa bulan (1 bulan di tengah malam) sebagai asal, Anda dapat dengan aman melewati Langkah 2 dan menggunakan diff1 sebagai diff2 . Itu karena asal + diff1 tidak pernah bisa> stempel waktu dalam kasus seperti itu. Namun, tujuan saya adalah memberikan alternatif yang setara secara logis untuk fungsi DATE_BUCKET yang akan berfungsi dengan benar untuk titik Asal mana pun, umum atau tidak. Jadi, saya akan menyertakan logika untuk Langkah 2 dalam contoh saya, tetapi ingatlah ketika Anda mengidentifikasi kasus di mana langkah ini tidak relevan, Anda dapat dengan aman menghapus bagian di mana Anda mengurangi output dari ekspresi CASE.

Pada Langkah 3 Anda mengidentifikasi berapa banyak unit bagian tanggal ada di seluruh ember yang ada di antara asal dan stempel waktu . Saya akan merujuk nilai ini sebagai diff3 . Ini dapat dilakukan dengan rumus berikut:

diff3 = diff2 / <bucket width> * <bucket width>

Triknya di sini adalah ketika menggunakan operator pembagian / di T-SQL dengan operan integer, Anda mendapatkan pembagian integer. Misalnya, 3 / 2 di T-SQL adalah 1 dan bukan 1,5. Ekspresi diff2 / memberi Anda jumlah seluruh ember yang ada di antara asal dan stempel waktu (1 dalam kasus kami). Mengalikan hasilnya dengan lebar bucket kemudian memberi Anda jumlah unit bagian tanggal yang ada di dalam seluruh ember itu (2 dalam kasus kami). Rumus ini diterjemahkan ke ekspresi berikut dalam T-SQL:

SELECT
  ( DATEDIFF(month, @origin, @timestamp)
      - CASE
          WHEN DATEADD(
                 month, 
                 DATEDIFF(month, @origin, @timestamp), 
                 @origin) > @timestamp 
            THEN 1
          ELSE 0
        END )  / @bucketwidth * @bucketwidth AS diff3;

Ekspresi ini mengembalikan 2, yang merupakan jumlah bulan di seluruh bucket 2 bulan yang ada di antara dua input.

Pada Langkah 4, yang merupakan langkah terakhir, Anda menambahkan diff3 unit bagian tanggal ke asal untuk menghitung awal ember berisi. Berikut kode untuk mencapai ini:

SELECT DATEADD(
         month, 
         ( DATEDIFF(month, @origin, @timestamp)
             - CASE
                 WHEN DATEADD(
                        month, 
                        DATEDIFF(month, @origin, @timestamp), 
                        @origin) > @timestamp 
                   THEN 1
                 ELSE 0
               END ) / @bucketwidth * @bucketwidth,
         @origin);

Kode ini menghasilkan output berikut:

---------------------------
2021-03-15 00:00:00.0000000

Seperti yang Anda ingat, ini adalah output yang sama yang dihasilkan oleh fungsi DATE_BUCKET untuk input yang sama.

Saya sarankan Anda mencoba ekspresi ini dengan berbagai input dan bagian. Saya akan menunjukkan beberapa contoh di sini, tetapi silakan coba sendiri.

Berikut adalah contoh di mana asal hanya sedikit di depan stempel waktu di bulan:

DECLARE 
  @timestamp   AS DATETIME2 = '20210510 06:30:00',
  @bucketwidth AS INT = 2,
  @origin      AS DATETIME2 = '20210110 06:30:01';
 
-- SELECT DATE_BUCKET(week, @bucketwidth, @timestamp, @origin);
 
SELECT DATEADD(
         month, 
         ( DATEDIFF(month, @origin, @timestamp)
             - CASE
                 WHEN DATEADD(
                        month, 
                        DATEDIFF(month, @origin, @timestamp), 
                        @origin) > @timestamp 
                   THEN 1
                 ELSE 0
               END ) / @bucketwidth * @bucketwidth,
         @origin);

Kode ini menghasilkan output berikut:

---------------------------
2021-03-10 06:30:01.0000000

Perhatikan bahwa awal dari ember berisi adalah pada bulan Maret.

Berikut adalah contoh di mana asal berada pada titik yang sama dalam satu bulan dengan stempel waktu :

DECLARE 
  @timestamp   AS DATETIME2 = '20210510 06:30:00',
  @bucketwidth AS INT = 2,
  @origin      AS DATETIME2 = '20210110 06:30:00';
 
-- SELECT DATE_BUCKET(week, @bucketwidth, @timestamp, @origin);
 
SELECT DATEADD(
         month, 
         ( DATEDIFF(month, @origin, @timestamp)
             - CASE
                 WHEN DATEADD(
                        month, 
                        DATEDIFF(month, @origin, @timestamp), 
                        @origin) > @timestamp 
                   THEN 1
                 ELSE 0
               END ) / @bucketwidth * @bucketwidth,
         @origin);

Kode ini menghasilkan output berikut:

---------------------------
2021-05-10 06:30:00.0000000

Perhatikan bahwa kali ini ember berisi dimulai pada bulan Mei.

Berikut ini contoh dengan ember 4 minggu:

DECLARE 
  @timestamp   AS DATETIME2 = '20210303 21:22:11',
  @bucketwidth AS INT = 4,
  @origin      AS DATETIME2 = '20210115';
 
-- SELECT DATE_BUCKET(week, @bucketwidth, @timestamp, @origin);
 
SELECT DATEADD(
         week, 
         ( DATEDIFF(week, @origin, @timestamp)
             - CASE
                 WHEN DATEADD(
                        week, 
                        DATEDIFF(week, @origin, @timestamp), 
                        @origin) > @timestamp 
                   THEN 1
                 ELSE 0
               END ) / @bucketwidth * @bucketwidth,
         @origin);

Perhatikan bahwa kode menggunakan minggu bagian kali ini.

Kode ini menghasilkan output berikut:

---------------------------
2021-02-12 00:00:00.0000000

Berikut ini contoh dengan ember 15 menit:

DECLARE 
  @timestamp   AS DATETIME2 = '20210203 21:22:11',
  @bucketwidth AS INT = 15,
  @origin      AS DATETIME2 = '19000101';
 
-- SELECT DATE_BUCKET(minute, @bucketwidth, @timestamp);
 
SELECT DATEADD(
         minute, 
         ( DATEDIFF(minute, @origin, @timestamp)
             - CASE
                 WHEN DATEADD(
                        minute, 
                        DATEDIFF(minute, @origin, @timestamp), 
                        @origin) > @timestamp 
                   THEN 1
                 ELSE 0
               END ) / @bucketwidth * @bucketwidth,
         @origin);

Kode ini menghasilkan output berikut:

---------------------------
2021-02-03 21:15:00.0000000

Perhatikan bahwa bagiannya adalah menit . Dalam contoh ini, Anda ingin menggunakan ember 15 menit yang dimulai dari bagian bawah jam, jadi titik asal yang berada di bagian bawah jam mana pun akan berfungsi. Faktanya, titik asal yang memiliki satuan menit 00, 15, 30 atau 45 dengan nol di bagian bawah, dengan tanggal dan jam apa pun akan berfungsi. Jadi default yang digunakan fungsi DATE_BUCKET untuk input Origin akan bekerja. Tentu saja, saat menggunakan ekspresi kustom, Anda harus eksplisit tentang titik asal. Jadi, untuk bersimpati dengan fungsi DATE_BUCKET, Anda dapat menggunakan tanggal dasar di tengah malam seperti yang saya lakukan pada contoh di atas.

Kebetulan, dapatkah Anda melihat mengapa ini akan menjadi contoh yang baik di mana sangat aman untuk melewati Langkah 2 dalam solusi? Jika Anda memang memilih untuk melewati Langkah 2, Anda mendapatkan kode berikut:

DECLARE 
  @timestamp   AS DATETIME2 = '20210203 21:22:11',
  @bucketwidth AS INT = 15,
  @origin      AS DATETIME2 = '19000101';
 
-- SELECT DATE_BUCKET(minute, @bucketwidth, @timestamp);
 
SELECT DATEADD( 
    minute, 
    ( DATEDIFF( minute, @origin, @timestamp ) ) / @bucketwidth * @bucketwidth, 
    @origin 
);

Jelas, kode menjadi jauh lebih sederhana ketika Langkah 2 tidak diperlukan.

Mengelompokkan dan menggabungkan data menurut tanggal dan waktu

Ada kasus di mana Anda perlu mengelompokkan data tanggal dan waktu yang tidak memerlukan fungsi canggih atau ekspresi yang berat. Misalnya, Anda ingin membuat kueri tampilan Sales.OrderValues ​​dalam database TSQLV5, mengelompokkan data setiap tahun, dan menghitung jumlah dan nilai pesanan total per tahun. Jelas, cukup menggunakan fungsi YEAR(orderdate) sebagai elemen set pengelompokan, seperti:

USE TSQLV5;
 
SELECT
  YEAR(orderdate) AS orderyear,
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
GROUP BY YEAR(orderdate)
ORDER BY orderyear;

Kode ini menghasilkan output berikut:

orderyear   numorders   totalvalue
----------- ----------- -----------
2017        152         208083.99
2018        408         617085.30
2019        270         440623.93

Tetapi bagaimana jika Anda ingin mengelompokkan data berdasarkan tahun fiskal organisasi Anda? Beberapa organisasi menggunakan tahun fiskal untuk tujuan akuntansi, anggaran, dan pelaporan keuangan, tidak selaras dengan tahun kalender. Katakanlah, misalnya, bahwa tahun fiskal organisasi Anda beroperasi pada kalender fiskal Oktober hingga September, dan dilambangkan dengan tahun kalender di mana tahun fiskal berakhir. Jadi suatu peristiwa yang terjadi pada tanggal 3 Oktober 2018 termasuk dalam tahun anggaran yang dimulai pada tanggal 1 Oktober 2018, berakhir pada tanggal 30 September 2019, dan dilambangkan dengan tahun 2019.

Ini cukup mudah dicapai dengan fungsi DATE_BUCKET, seperti:

DECLARE 
  @bucketwidth AS INT = 1,
  @origin      AS DATETIME2 = '19001001'; -- this is Oct 1 of some year
 
SELECT 
  YEAR(startofbucket) + 1 AS fiscalyear,
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
  CROSS APPLY ( VALUES( DATE_BUCKET( year, @bucketwidth, orderdate, @origin ) ) ) AS A(startofbucket)
GROUP BY startofbucket
ORDER BY startofbucket;

Dan inilah kode yang menggunakan padanan logika khusus dari fungsi DATE_BUCKET:

DECLARE 
  @bucketwidth AS INT = 1,
  @origin      AS DATETIME2 = '19001001'; -- this is Oct 1 of some year
 
SELECT
  YEAR(startofbucket) + 1 AS fiscalyear,
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
  CROSS APPLY ( VALUES( 
    DATEADD(
      year, 
      ( DATEDIFF(year, @origin, orderdate)
          - CASE
              WHEN DATEADD(
                     year, 
                     DATEDIFF(year, @origin, orderdate), 
                     @origin) > orderdate 
                THEN 1
              ELSE 0
            END ) / @bucketwidth * @bucketwidth,
      @origin) ) ) AS A(startofbucket)
GROUP BY startofbucket
ORDER BY startofbucket;

Kode ini menghasilkan output berikut:

fiscalyear  numorders   totalvalue
----------- ----------- -----------
2017        70          79728.58
2018        370         563759.24
2019        390         622305.40

Saya menggunakan variabel di sini untuk lebar bucket dan titik asal untuk membuat kode lebih digeneralisasikan, tetapi Anda dapat menggantinya dengan konstanta jika Anda selalu menggunakan yang sama, lalu menyederhanakan penghitungan yang sesuai.

Sebagai sedikit variasi di atas, misalkan tahun fiskal Anda berjalan dari 15 Juli dari satu tahun kalender hingga 14 Juli tahun kalender berikutnya, dan dilambangkan dengan tahun kalender yang menjadi awal tahun fiskal. Jadi peristiwa yang terjadi pada tanggal 18 Juli 2018 termasuk tahun fiskal 2018. Peristiwa yang terjadi pada tanggal 14 Juli 2018 termasuk tahun fiskal 2017. Dengan menggunakan fungsi DATE_BUCKET, Anda akan mencapai ini seperti ini:

DECLARE 
  @bucketwidth AS INT = 1,
  @origin      AS DATETIME2 = '19000715'; -- July 15 marks start of fiscal year
 
SELECT
  YEAR(startofbucket) AS fiscalyear, -- no need to add 1 here
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
  CROSS APPLY ( VALUES( DATE_BUCKET( year, @bucketwidth, orderdate, @origin ) ) ) AS A(startofbucket)
GROUP BY startofbucket
ORDER BY startofbucket;

Anda dapat melihat perubahan dibandingkan dengan contoh sebelumnya di komentar.

Dan inilah kode yang menggunakan logika khusus yang setara dengan fungsi DATE_BUCKET:

DECLARE 
  @bucketwidth AS INT = 1,
  @origin      AS DATETIME2 = '19000715';
 
SELECT
  YEAR(startofbucket) AS fiscalyear,
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
  CROSS APPLY ( VALUES( 
    DATEADD(
      year, 
      ( DATEDIFF(year, @origin, orderdate)
          - CASE
              WHEN DATEADD(
                     year, 
                     DATEDIFF(year, @origin, orderdate), 
                     @origin) > orderdate 
                THEN 1
              ELSE 0
            END ) / @bucketwidth * @bucketwidth,
      @origin) ) ) AS A(startofbucket)
GROUP BY startofbucket
ORDER BY startofbucket;

Kode ini menghasilkan output berikut:

fiscalyear  numorders   totalvalue
----------- ----------- -----------
2016        8           12599.88
2017        343         495118.14
2018        479         758075.20

Jelas, ada metode alternatif yang dapat Anda gunakan dalam kasus tertentu. Ambil contoh sebelum yang terakhir, di mana tahun fiskal berlangsung dari Oktober hingga September dan dilambangkan dengan tahun kalender di mana tahun fiskal berakhir. Dalam kasus seperti itu, Anda dapat menggunakan ekspresi berikut yang jauh lebih sederhana:

YEAR(orderdate) + CASE WHEN MONTH(orderdate) BETWEEN 10 AND 12 THEN 1 ELSE 0 END

Dan kemudian kueri Anda akan terlihat seperti ini:

SELECT
  fiscalyear,
  COUNT(*) AS numorders,
  SUM(val) AS totalvalue
FROM Sales.OrderValues
  CROSS APPLY ( VALUES( 
    YEAR(orderdate)
      + CASE 
          WHEN MONTH(orderdate) BETWEEN 10 AND 12 THEN 1 
          ELSE 0 
        END ) ) AS A(fiscalyear)
GROUP BY fiscalyear
ORDER BY fiscalyear;

Namun, jika Anda menginginkan solusi umum yang akan bekerja dalam lebih banyak kasus, dan Anda dapat membuat parameter, Anda tentu ingin menggunakan bentuk yang lebih umum. Jika Anda memiliki akses ke fungsi DATE_BUCKET, itu bagus. Jika tidak, Anda dapat menggunakan padanan logika khusus.

Kesimpulan

Fungsi DATE_BUCKET adalah fungsi yang cukup berguna yang memungkinkan Anda untuk mengelompokkan data tanggal dan waktu. Ini berguna untuk menangani data deret waktu, tetapi juga untuk mengelompokkan data apa pun yang melibatkan atribut tanggal dan waktu. Dalam artikel ini saya menjelaskan cara kerja fungsi DATE_BUCKET dan menyediakan logika ekuivalen khusus jika platform yang Anda gunakan tidak mendukungnya.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pernyataan SQL WHERE

  2. Tipe Data Tanggal Waktu T-SQL

  3. Panduan untuk Menyebarkan TimescaleDB dengan Docker

  4. Pengantar auto_explain:Cara Mencatat Rencana Kueri Postgres Lambat Secara Otomatis

  5. Kesalahan Umum Diagram ER