SSMS
 sql >> Baza danych >  >> Database Tools >> SSMS

Zakres dat dla zestawu tych samych danych

Rozwiązanie nierelacyjne

Nie sądzę, aby inne odpowiedzi były poprawne.

  • GROUP BY nie zadziała

  • Korzystanie z ROW_NUMBER() zmusza dane do struktury Record Filing System, która jest fizyczna, a następnie przetwarza je jako fizyczne rekordy. Przy ogromnych kosztach wydajności. Oczywiście pisanie takiego kodu zmusza cię do pomyślenia w kategoriach RFS zamiast myśleć w kategoriach relacyjnych.

  • Korzystanie z CTE jest takie samo. Iteracja po danych, zwłaszcza danych, które się nie zmieniają. Przy nieco innych ogromnych kosztach.

  • Kursory są zdecydowanie niewłaściwą rzeczą z różnych powodów. (a) Kursory wymagają kodu, a użytkownik zażądał widoku (b) Kursory porzucają silnik przetwarzania zestawów i powracają do przetwarzania wiersz po wierszu. Znowu nie jest wymagane. Jeśli programista w którymkolwiek z moich zespołów używa kursorów lub tabel tymczasowych w relacyjnej bazie danych (tj. nie w systemie archiwizacji rekordów), strzelam do nich.

Rozwiązanie relacyjne

  1. Twoje dane jest relacyjne, logiczne, te dwa podane dane kolumny to wszystko, co jest potrzebne.

  2. Oczywiście, aby uzyskać żądany raport, musimy utworzyć widok (relację pochodną), ale składa się on z samych SELECTów, co jest zupełnie inne niż przetwarzanie (konwertowanie go do pliku , który jest fizyczny, a następnie przetwarza plik; lub tabele tymczasowe; lub stoły robocze; lub CTE; lub ROW_Numer(); itp).

  3. Wbrew lamentom „teoretyków”, którzy mają agendę, SQL doskonale radzi sobie z danymi relacyjnymi. A Twoje dane są relacyjne.

Dlatego utrzymuj relacyjny sposób myślenia, relacyjny pogląd na dane i mentalność przetwarzania zbiorów. Każde wymaganie dotyczące raportu w relacyjnej bazie danych można spełnić za pomocą pojedynczego SELECT. Nie ma potrzeby cofania się do metod obsługi plików ISAM sprzed 1970 r.

Przyjmę, że klucz podstawowy (zestaw kolumn, które dają relacyjną unikatowość wiersza) to Date, i na podstawie podanych przykładowych danych typ danych to DATE.

Spróbuj tego:

    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, ogólna

Oczywiście jest to metoda, dlatego jest ogólna, może być użyta do określenia From_ i To_ dowolnego zakresu danych (tutaj Date zakres), na podstawie dowolnej zmiany danych (tutaj zmiana Price ).

Tutaj Twoje Dates są kolejne, więc określenie Date_Next jest proste:zwiększ Date o 1 dzień. Jeśli PK rośnie, ale nie kolejne (np. DateTime lub TimeStamp lub inny klucz), zmień tabelę pochodną X do:

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

Ciesz się.

Zachęcamy do komentowania, zadawania pytań itp.



  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. Zbyt wiele wartości parametrów spowalnia zapytanie

  2. Zatrzymaj SQL Server przed uruchomieniem, dopóki nie będzie potrzebny

  3. Skąd pobrać sun.jdbc.odbc.JdbcOdbcDriver (próba podłączenia wyjścia csv z Spoon do SSMS)

  4. Ograniczyć kolumnę varchar() do określonych wartości?

  5. Jak mogę sprawdzić, gdzie znajdują się tabulatory w edytorze SQL Server Management Studio?