sql >> Databáze >  >> Database Tools >> SSMS

Období pro sadu stejných dat

Nerelační řešení

Nemyslím si, že žádná z dalších odpovědí je správná.

  • GROUP BY nebude fungovat

  • Pomocí ROW_NUMBER() vnutí data do struktury systému evidence záznamů, která je fyzická, a poté je zpracuje jako fyzické záznamy. Za obrovské náklady na výkon. K napsání takového kódu vás to samozřejmě nutí přemýšlet z hlediska RFS namísto myšlení v relačních termínech.

  • Použití CTE je stejné. Iterace přes data, zejména data, která se nemění. Za trochu jiné masivní náklady.

  • Kurzory jsou rozhodně špatné z různých důvodů. (a) Kurzory vyžadují kód a vy jste požádali o zobrazení (b) Kurzory opustí jádro pro zpracování sady a vrátí se ke zpracování po řádcích. Opět není vyžadováno. Pokud vývojář v některém z mých týmů používá kurzory nebo dočasné tabulky v relační databázi (tj. nikoli v systému evidence záznamů), zastřelím je.

Relační řešení

  1. Vaše data je relační, logická, dvě dané data sloupce jsou vše, co je potřeba.

  2. Jistě, musíme vytvořit View (odvozený vztah), abychom získali požadovanou zprávu, ale to sestává z čistých SELECTů, což je zcela odlišné od zpracování (převedení na soubor , což je fyzické, a následné zpracování souboru; nebo dočasné tabulky; nebo pracovní stoly; nebo CTE; nebo Číslo_ŘÁDKU(); atd).

  3. Na rozdíl od lamentací "teoretiků", kteří mají agendu, SQL zvládá Relační data naprosto dobře. A vaše data jsou relační.

Udržujte proto relační myšlení, relační pohled na data a mentalitu zpracování souborů. Každý požadavek na sestavu přes relační databázi lze splnit pomocí jediného SELECT. Není třeba se vracet k metodám zpracování souborů ISAM před rokem 1970.

Budu předpokládat, že primární klíč (soubor sloupců, které poskytují relační jedinečnost řádku) je Date, a na základě uvedených příkladů dat je datový typ DATE.

Zkuste toto:

    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

Metoda, obecná

Samozřejmě se jedná o metodu, proto je obecná, lze ji použít k určení From_ a To_ libovolného rozsahu dat (zde Date rozsah), na základě jakékoli změny dat (zde změna Price ).

Zde jsou vaše Dates jsou po sobě jdoucí, takže určení Date_Next je jednoduché:zvyšte Date o 1 den. Pokud se PK zvyšuje, ale ne po sobě jdoucích (např. DateTime nebo TimeStamp nebo nějaký jiný klíč), změňte odvozenou tabulku X komu:

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

Užijte si to.

Prosím, neváhejte komentovat, klást otázky atd.



  1. Odesílání dat, jako jsou celá čísla a textové řetězce, z telefonu do webové databáze

  2. Chyba MySQL:Duplicitní záznam pro primární klíč

  3. phpMyAdmin + CentOS 6.0 – Zakázáno

  4. Vytvořte propojený server v management studiu s databází SAGE 50 US pomocí správce zdroje dat ODBC