sql >> Databasteknik >  >> Database Tools >> SSMS

Datumintervall för uppsättning av samma data

Icke-relationell lösning

Jag tror inte att något av andra svar är korrekta.

  • GROUP BY fungerar inte

  • Använder ROW_NUMBER() tvingar in uppgifterna i en arkiveringssystemstruktur, som är fysisk, och bearbetar den sedan som fysiska arkiv. Till en enorm prestationskostnad. Naturligtvis, för att skriva sådan kod, tvingar den dig att tänka i termer av RFS istället för att tänka i relationella termer.

  • Att använda CTE är samma sak. Itererar genom data, särskilt data som inte förändras. Till en lite annorlunda massiv kostnad.

  • Markörer är definitivt fel av olika anledningar. (a) Markörer kräver kod, och du har begärt en vy (b) Markörer överger uppsättningsbearbetningsmotorn och återgår till rad-för-rad-behandling. Återigen, inte nödvändigt. Om en utvecklare i något av mina team använder markörer eller tillfälliga tabeller i en relationsdatabas (dvs. inte ett registerarkiveringssystem), skjuter jag dem.

Relationell lösning

  1. Dina data är Relationell, logisk, de två givna data kolumner är allt som behövs.

  2. Visst, vi måste bilda en vy (härledd relation) för att få den önskade rapporten, men den består av rena SELECT, vilket skiljer sig ganska mycket från bearbetning (konvertera den till en fil , som är fysisk, och bearbetar sedan filen; eller temp tabeller; eller arbetsbord; eller CTE; eller ROW_Number(); etc).

  3. I motsats till klagomålen från "teoretiker", som har en agenda, hanterar SQL Relationell data utmärkt. Och din data är relationell.

Upprätthåll därför ett relationellt tänkesätt, en relationell syn på data och en uppsättningsbearbetningsmentalitet. Varje rapportkrav över en relationsdatabas kan uppfyllas med ett enda SELECT. Det finns inget behov av att gå tillbaka till ISAM-filhanteringsmetoder före 1970.

Jag antar att den primära nyckeln (uppsättningen kolumner som ger en relationell rad unikhet) är Date, och baserat på exempeldata som ges är datatypen DATE.

Prova detta:

    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

Metod, Generisk

Naturligtvis är detta en metod, därför är den generisk, den kan användas för att bestämma From_ och To_ för alla dataintervall (här ett Date intervall), baserat på eventuell dataändring (här, en ändring i Price ).

Här, dina Date är på varandra följande, så bestämningen av Date_Next är enkelt:öka Date med 1 dag. Om PK ökar men inte på varandra följande (t.ex. DateTime eller TimeStamp eller någon annan nyckel), ändra den härledda tabellen X till:

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

Njut.

Kommentera gärna, ställ frågor etc.



  1. Installera och säkra phpMyAdmin med Apache på Debian 9

  2. Finns det något sätt att programmässigt köra en fråga med Inkludera faktisk körningsplan och se om något indexförslag eller inte

  3. PHP 7 med phpmyadmin ger massor av avskrivningsmeddelanden

  4. phpMyAdmin - Fel Mysql-fel under sessionsstart