SSMS
 sql >> Teknologi Basis Data >  >> Database Tools >> SSMS

Rentang Tanggal untuk kumpulan data yang sama

Solusi Non-relasional

Saya tidak berpikir ada jawaban lain yang benar.

  • GROUP BY tidak akan berfungsi

  • Menggunakan ROW_NUMBER() memaksa data ke dalam struktur Sistem Pengarsipan Rekam, yang bersifat fisik, dan kemudian memprosesnya sebagai arsip fisik. Dengan biaya kinerja yang besar. Tentu saja, untuk menulis kode seperti itu, Anda harus berpikir dalam hal RFS daripada berpikir dalam istilah Relasional.

  • Menggunakan CTE adalah sama. Iterasi melalui data, terutama data yang tidak berubah. Dengan biaya besar yang sedikit berbeda.

  • Kursor jelas merupakan hal yang salah karena serangkaian alasan yang berbeda. (a) Kursor memerlukan kode, dan Anda telah meminta Tampilan (b) Kursor meninggalkan mesin pemrosesan set, dan kembali ke pemrosesan baris demi baris. Sekali lagi, tidak wajib. Jika seorang pengembang di salah satu tim saya menggunakan kursor atau tabel sementara pada Basis Data Relasional (yaitu, bukan Sistem Pengarsipan Catatan), saya memotret mereka.

Solusi Relasional

  1. Data Your Anda adalah Relasional, logis, keduanya memberikan data kolom adalah semua yang diperlukan.

  2. Tentu, kita harus membentuk View (Relasi turunan), untuk mendapatkan laporan yang diinginkan, tetapi itu terdiri dari SELECT murni, yang sangat berbeda dengan pemrosesan (mengonversinya menjadi file , yang bersifat fisik, lalu memproses file; atau tabel temp; atau meja kerja; atau CTE; atau ROW_Number(); dll).

  3. Berlawanan dengan ratapan "para ahli teori", yang memiliki agenda, SQL menangani data Relasional dengan sangat baik. Dan data Anda adalah Relasional.

Oleh karena itu, pertahankan pola pikir relasional, pandangan relasional dari data, dan mentalitas pemrosesan yang ditetapkan. Setiap persyaratan laporan melalui Database Relasional dapat dipenuhi menggunakan satu SELECT. Tidak perlu mundur ke metode penanganan File ISAM sebelum tahun 1970.

Saya akan menganggap Kunci Utama (kumpulan kolom yang memberikan keunikan baris Relasional) adalah Date, dan berdasarkan contoh data yang diberikan, Tipe Datanya adalah DATE.

Coba ini:

    CREATE VIEW MyTable_Base_V          -- Foundation View
    AS
        SELECT  Date,
                Date_Next,
                Price
            FROM (
            -- Derived Table: project rows with what we need
            SELECT  Date,
                    [Date_Next] = DATEADD( DD, 1, O.Date ),
                    Price,
                    [Price_Next] = (

                SELECT Price            -- NULL if not exists
                    FROM MyTable
                    WHERE Date = DATEADD( DD, 1, O.Date )
                    )

                FROM MyTable MT

                ) AS X
            WHERE Price != Price_Next   -- exclude unchanging rows
    GO

    CREATE VIEW MyTable_V               -- Requested View
    AS
        SELECT  [Date_From] = (
            --  Date of the previous row
            SELECT MAX( Date_Next )     -- previous row
                FROM MyTable_V
                WHERE Date_Next < MT.Date
                ),

                [Date_To] = Date,       -- this row
                Price
            FROM MyTable_Base_V MT
    GO

    SELECT  *
        FROM MyTable_V
    GO

Metode, Umum

Tentu saja ini adalah metode, oleh karena itu generik, dapat digunakan untuk menentukan From_ dan To_ rentang data apa pun (di sini, Date rentang), berdasarkan perubahan data apa pun (di sini, perubahan Price ).

Di sini, Date berturut-turut, jadi penentuan Date_Next sederhana:tambahkan Date dengan 1 hari. Jika PK meningkat tetapi tidak berturut-turut (mis. DateTime atau TimeStamp atau beberapa Kunci lainnya), ubah Tabel Turunan X ke:

    -- Derived Table: project rows with what we need
    SELECT  DateTime,
            [DateTime_Next] = (
            -- first row > this row
        SELECT  TOP 1
                DateTime                -- NULL if not exists
            FROM MyTable
            WHERE DateTime > MT.DateTime
            ),

            Price,
            [Price_Next] = (
            -- first row > this row
        SELECT  TOP 1
                Price                   -- NULL if not exists
            FROM MyTable
            WHERE DateTime > MT.DateTime
            )

        FROM MyTable MT

Selamat menikmati.

Silakan berkomentar, mengajukan pertanyaan, dll.



  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. SQL Server Management Studio TIDAK mengizinkan saya membuat beberapa kunci asing ke beberapa kunci utama

  2. Alternatif Mac untuk studio manajemen server SQL?

  3. Tugas skrip SSIS gagal skrip versi 15.0?

  4. Hubungkan EF ke studio Manajemen SQL Server

  5. Studio Manajemen SQL Server tidak akan mulai - Jenis perpustakaan tidak dapat ditemukan