SSMS
 sql >> база данни >  >> Database Tools >> SSMS

Период от време за набор от същите данни

Нерелационно решение

Не мисля, че някой от другите отговори е правилен.

  • GROUP BY няма да работи

  • Използване на ROW_NUMBER() принуждава данните в структура на системата за архивиране на записи, която е физическа, и след това ги обработва като физически записи. При огромна цена за производителност. Разбира се, за да напишете такъв код, той ви принуждава да размислите по отношение на RFS вместо да мислим в релационни термини.

  • Използването на CTEs е същото. Итерация през данните, особено данни, които не се променят. На малко по-различна огромна цена.

  • Курсорите определено са грешно нещо поради различни причини. (a) Курсорите изискват код, а вие сте поискали изглед (b) Курсорите изоставят механизма за обработка на набори и се връщат към обработка ред по ред. Отново не е задължително. Ако разработчик в някой от моите екипи използва курсори или временни таблици в релационна база данни (т.е. не система за архивиране на записи), аз ги снимам.

Релационно решение

  1. Вашите данни е Релационна, логична, двете дадени данни колони са всичко, което е необходимо.

  2. Разбира се, трябва да формираме изглед (получена релация), за да получим желания отчет, но той се състои от чисти SELECT, което е доста различно от обработката (преобразуването му във файл , което е физическо, и след това обработвафайла; или временни таблици; или работни маси; или CTEs; или ROW_Number(); и др.).

  3. Противно на оплакванията на "теоретици", които имат дневен ред, SQL се справя перфектно с релационните данни. И вашите данни са релационни.

Затова поддържайте релационен начин на мислене, релационен изглед на данните и манталитет за обработка на набори. Всяко изискване за отчет върху релационна база данни може да бъде изпълнено с помощта на един SELECT. Няма нужда да се връщате към методите за обработка на файлове от преди 1970 г. ISAM.

Предполагам, че първичният ключ (наборът от колони, които дават уникалност на релационния ред) е Date, и въз основа на дадените примерни данни, типът на данните е DATE.

Опитайте това:

    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

Метод, общ

Разбира се, това е метод, следователно е общ, може да се използва за определяне на From_ и To_ на всеки диапазон от данни (тук Date диапазон), въз основа на всяка промяна на данните (тук промяна в Price). ).

Ето вашите Dates са последователни, така че определянето на Date_Next е просто:увеличете Date до 1 ден. Ако PK се увеличава, но не последователни (напр. DateTime или TimeStamp или някакъв друг ключ), променете извлечената таблица X до:

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

Насладете се.

Моля, не се колебайте да коментирате, да задавате въпроси и т.н.



  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. Защо SSMS променя съхранените ми процедури (преформатиране, промяна на exec на EXECUTE и т.н.)

  2. Как да създам SQL таблица под различна схема?

  3. По-сигурна и продуктивна разработка на база данни и код в актуализиран SQL Complete

  4. Защо синтаксисът на Microsoft SSMS подчертава думата конфигурация?

  5. възстановяване на раздели след повторно отваряне на SQL Server Management Studio