SSMS
 sql >> Cơ Sở Dữ Liệu >  >> Database Tools >> SSMS

Phạm vi ngày cho tập hợp dữ liệu giống nhau

Giải pháp không quan hệ

Tôi không nghĩ bất kỳ câu trả lời nào khác là đúng.

  • GROUP BY sẽ không hoạt động

  • Sử dụng ROW_NUMBER() buộc dữ liệu vào cấu trúc Hệ thống Lưu trữ Bản ghi, là cấu trúc vật lý, và sau đó xử lý nó dưới dạng các bản ghi vật lý. Với chi phí hiệu suất lớn. Tất nhiên, để viết mã như vậy, nó buộc bạn phải suy nghĩ về RFS thay vì suy nghĩ về Thuật ngữ quan hệ.

  • Sử dụng CTE cũng vậy. Lặp đi lặp lại dữ liệu, đặc biệt là dữ liệu không thay đổi. Với chi phí lớn hơi khác một chút.

  • Con trỏ chắc chắn là thứ sai vì nhiều lý do khác nhau. (a) Con trỏ yêu cầu mã và bạn đã yêu cầu Chế độ xem (b) Con trỏ từ bỏ công cụ xử lý thiết lập và trở lại xử lý từng hàng. Một lần nữa, không bắt buộc. Nếu một nhà phát triển trong bất kỳ nhóm nào của tôi sử dụng con trỏ hoặc bảng tạm thời trên Cơ sở dữ liệu quan hệ (tức là không phải Hệ thống lưu hồ sơ), tôi sẽ bắn họ.

Giải pháp quan hệ

  1. Dữ liệu của bạn là Quan hệ, lôgic, hai dữ liệu đã cho cột là tất cả những gì cần thiết.

  2. Chắc chắn, chúng tôi phải tạo một Chế độ xem (Quan hệ dẫn xuất), để có được báo cáo mong muốn, nhưng báo cáo đó bao gồm các CHỌN thuần túy, điều này hoàn toàn khác với quá trình xử lý (chuyển đổi nó thành tệp , là vật lý và sau đó xử lý tệp ; hoặc bảng tạm thời; hoặc bảng làm việc; hoặc CTE; hoặc ROW_Number (); vv).

  3. Trái ngược với những lời than thở của các "nhà lý thuyết", những người có một chương trình nghị sự, SQL xử lý dữ liệu quan hệ một cách hoàn hảo. Và dữ liệu của bạn là Quan hệ.

Do đó, hãy duy trì tư duy Quan hệ, quan điểm Quan hệ về dữ liệu và tư duy xử lý tập hợp. Mọi yêu cầu báo cáo trên Cơ sở dữ liệu quan hệ đều có thể được đáp ứng bằng cách sử dụng một CHỌN duy nhất. Không cần phải hồi quy về các phương pháp xử lý tệp ISAM trước năm 1970.

Tôi sẽ giả sử Khóa chính (tập hợp các cột cung cấp tính duy nhất cho hàng Quan hệ) là Date, và dựa trên dữ liệu mẫu được cung cấp, Datatype là DATE.

Hãy thử điều này:

    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

Phương pháp, Chung

Tất nhiên đây là một phương pháp, do đó nó là chung chung, nó có thể được sử dụng để xác định From_To_ của bất kỳ phạm vi dữ liệu nào (tại đây, một Date phạm vi), dựa trên bất kỳ thay đổi dữ liệu nào (ở đây, thay đổi về Price ).

Đây, Date của bạn liên tiếp, vì vậy việc xác định Date_Next rất đơn giản:tăng Date trước 1 ngày. Nếu PK đang tăng nhưng không liên tiếp (ví dụ:DateTime hoặc TimeStamp hoặc một số Khóa khác), thay đổi Bảng gốc X tới:

    -- 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

Hãy tận hưởng.

Vui lòng bình luận, đặt câu hỏi, v.v.



  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. SQL Server 2008 R2 intellisense không hoạt động

  2. ALTER DATABASE không thành công vì không thể đặt khóa trên cơ sở dữ liệu

  3. SSMS:Cách nhập (Sao chép / Dán) dữ liệu từ excel

  4. Lưu kết quả với tiêu đề trong Sql Server Management Studio

  5. Lỗi máy chủ Microsoft SQL:18456