Database
 sql >> Baza danych >  >> RDS >> Database

Rozpoznawanie wzorców wierszy w SQL

Norma ISO/IEC 9075:2016 lub w skrócie SQL:2016 wprowadza obsługę głębokiej koncepcji o nazwie Rozpoznawanie wzorców wierszy (RPR) w SQL. Wysłałem sugestię ulepszenia SQL Server poprzez dodanie obsługi RPR w T-SQL, ale byłem dość ograniczony w miejscu, w którym musiałem przekazać informację zwrotną. Celem tego artykułu jest dostarczenie więcej szczegółów na temat propozycji i miejmy nadzieję, że przekonasz się o jej znaczeniu i oddasz swój głos.

Tło

Podobnie jak w przypadku używania wyrażeń regularnych do identyfikowania wzorców w ciągu, z RPR używasz wyrażeń regularnych do identyfikowania wzorców w sekwencji wierszy. W przypadku każdego dopasowania do wzorca można zwrócić wiersz podsumowania, taki jak w przypadku grupowania, lub wiersze szczegółowe z obliczonymi miarami w odniesieniu do podsekwencji dopasowania. RPR ma nieograniczone praktyczne zastosowania, w tym identyfikację wzorców aktywności na giełdzie (zarówno prawidłowe wzorce z wartością handlową, jak i potencjalnie nielegalne lub podejrzane wzorce), obsługę szeregów czasowych, wykrywanie oszustw, obsługę materiałów, aplikacje wysyłkowe, sekwencjonowanie DNA, luki i wyspy, góra N na grupę i wiele innych.

Dla mnie RPR to kolejny krok w ewolucji funkcji okien, o wyższym poziomie zaawansowania i rozszerzonej użyteczności. Jeśli uważasz, że funkcje okna są głębokie i przydatne, RPR naprawdę upiecze ci makaron. Podobnie jak funkcje okien, RPR obsługuje partycjonowanie i porządkowanie. Zazwyczaj będziesz szukać dopasowań wzorców w każdej partycji niezależnie, w oparciu o wskazaną kolejność. Podobnie jak funkcje okien, RPR nadaje się do dobrej optymalizacji, z możliwością polegania na kolejności indeksów, aby uniknąć sortowania danych.

Omówienie RPR, w tym ilustrowane przykłady, można znaleźć w 90-stronicowym raporcie technicznym ISO/IEC TR 19075-5 (dostępnym bezpłatnie).

Można go również znaleźć w dokumencie ISO/IEC 9075-2:2016, Technologia informacyjna — Języki baz danych — SQL — Część 2:Fundament (SQL/Foundation) (dostępny do zakupu).

Standard SQL:2016 zapewnia dwie główne funkcje związane z RPR:

  • Funkcja R010, „Rozpoznawanie wzorców wierszy:klauzula FROM”
  • Funkcja R020, „Rozpoznawanie wzorców wierszy:klauzula WINDOW”
  • Standard wspomina również o funkcji R030, „Rozpoznawanie wzorców wierszy:pełna obsługa agregacji”, bez której funkcje agregujące nie mogą określać DISTINCT ani .

    Jak dotąd jedyną platformą, jaką znam z zaimplementowaną funkcją R010, jest Oracle. Nie znam jeszcze żadnej platformy, która zaimplementowałaby R020.

    Funkcja R010, „Rozpoznawanie wzorców wierszy:klauzula FROM”

    Funkcja R010 definiuje operator klauzuli/tabeli o nazwie MATCH_RECOGNIZE, którego używasz w klauzuli FROM. Dane wejściowe to tabela lub wyrażenie tabelowe, a dane wyjściowe to tabela wirtualna. Kontekst jest podobny do innych operatorów tabel, takich jak JOIN, APPLY, PIVOT i UNPIVOT. Oto składnia zapytania korzystającego z tej funkcji:

    SELECT <select list> 
    FROM <source table> 
      MATCH_RECOGNIZE 
      ( 
        [ PARTITION BY <partition list> ]
        [ ORDER BY <order by list> ]
        [ MEASURES <measure list> ]
        [ <row pattern rows per match> ::= ONE ROW PER MATCH | ALL ROWS PER MATCH ]
        [ AFTER MATCH <skip to option>
        PATTERN ( <row pattern> )
        [ SUBSET <subset list> ]
        DEFINE <definition list> 
      ) AS <table alias>;

    Jako przykład zaadaptowany ze wspomnianego raportu technicznego załóżmy, że otrzymujesz tabelę dbo.Ticker z symbolem kolumny, datą transakcji i ceną. Użyj poniższego kodu, aby utworzyć tabelę, wypełnić ją przykładowymi danymi i wykonać zapytanie:

    SET NOCOUNT ON;
     
    USE tempdb;
     
    DROP TABLE IF EXISTS dbo.Ticker;
     
    CREATE TABLE dbo.Ticker
    (
      symbol    VARCHAR(10)    NOT NULL,
      tradedate DATE           NOT NULL,
      price     NUMERIC(12, 2) NOT NULL,
      CONSTRAINT PK_Ticker
        PRIMARY KEY (symbol, tradedate)
    );
    GO
     
    INSERT INTO dbo.Ticker(symbol, tradedate, price) VALUES
      ('STOCK1', '20190212', 150.00),  ('STOCK1', '20190213', 151.00),  ('STOCK1', '20190214', 148.00),
      ('STOCK1', '20190215', 146.00),  ('STOCK1', '20190218', 142.00),  ('STOCK1', '20190219', 144.00),
      ('STOCK1', '20190220', 152.00),  ('STOCK1', '20190221', 152.00),  ('STOCK1', '20190222', 153.00),
      ('STOCK1', '20190225', 154.00),  ('STOCK1', '20190226', 154.00),  ('STOCK1', '20190227', 154.00),
      ('STOCK1', '20190228', 153.00),  ('STOCK1', '20190301', 145.00),  ('STOCK1', '20190304', 140.00),
      ('STOCK1', '20190305', 142.00),  ('STOCK1', '20190306', 143.00),  ('STOCK1', '20190307', 142.00),
      ('STOCK1', '20190308', 140.00),  ('STOCK1', '20190311', 138.00),  ('STOCK2', '20190212', 330.00),
      ('STOCK2', '20190213', 329.00),  ('STOCK2', '20190214', 329.00),  ('STOCK2', '20190215', 326.00),
      ('STOCK2', '20190218', 325.00),  ('STOCK2', '20190219', 326.00),  ('STOCK2', '20190220', 328.00),
      ('STOCK2', '20190221', 326.00),  ('STOCK2', '20190222', 320.00),  ('STOCK2', '20190225', 317.00),
      ('STOCK2', '20190226', 319.00),  ('STOCK2', '20190227', 325.00),  ('STOCK2', '20190228', 322.00),
      ('STOCK2', '20190301', 324.00),  ('STOCK2', '20190304', 321.00),  ('STOCK2', '20190305', 319.00),
      ('STOCK2', '20190306', 322.00),  ('STOCK2', '20190307', 326.00),  ('STOCK2', '20190308', 326.00),
      ('STOCK2', '20190311', 324.00);
     
    SELECT symbol, tradedate, price FROM dbo.Ticker;

    Ten kod generuje następujące dane wyjściowe:

    symbol  tradedate   price
    ------  ----------  ------ 
    STOCK1  2019-02-12  150.00
    STOCK1  2019-02-13  151.00
    STOCK1  2019-02-14  148.00
    STOCK1  2019-02-15  146.00
    STOCK1  2019-02-18  142.00
    STOCK1  2019-02-19  144.00
    STOCK1  2019-02-20  152.00
    STOCK1  2019-02-21  152.00
    STOCK1  2019-02-22  153.00
    STOCK1  2019-02-25  154.00
    STOCK1  2019-02-26  154.00
    STOCK1  2019-02-27  154.00
    STOCK1  2019-02-28  153.00
    STOCK1  2019-03-01  145.00
    STOCK1  2019-03-04  140.00
    STOCK1  2019-03-05  142.00
    STOCK1  2019-03-06  143.00
    STOCK1  2019-03-07  142.00
    STOCK1  2019-03-08  140.00
    STOCK1  2019-03-11  138.00
    STOCK2  2019-02-12  330.00
    STOCK2  2019-02-13  329.00
    STOCK2  2019-02-14  329.00
    STOCK2  2019-02-15  326.00
    STOCK2  2019-02-18  325.00
    STOCK2  2019-02-19  326.00
    STOCK2  2019-02-20  328.00
    STOCK2  2019-02-21  326.00
    STOCK2  2019-02-22  320.00
    STOCK2  2019-02-25  317.00
    STOCK2  2019-02-26  319.00
    STOCK2  2019-02-27  325.00
    STOCK2  2019-02-28  322.00
    STOCK2  2019-03-01  324.00
    STOCK2  2019-03-04  321.00
    STOCK2  2019-03-05  319.00
    STOCK2  2019-03-06  322.00
    STOCK2  2019-03-07  326.00
    STOCK2  2019-03-08  326.00
    STOCK2  2019-03-11  324.00
    
    40 row(s) affected.

    Poniższe zapytanie identyfikuje wzorce reprezentujące kształty V w cenie akcji (okres ze ściśle spadającą ceną, po którym następuje okres ze ściśle rosnącą ceną), używając JEDEN WIERSZ NA DOPASOWANIE jako wiersze wzorców wierszy na dopasowanie opcja:

    SELECT
      MR.symbol, MR.matchnum, MR.startdate, MR.startprice,
      MR.bottomdate, MR.bottomprice, MR.enddate, MR.endprice, MR.maxprice
    FROM dbo.Ticker
      MATCH_RECOGNIZE
      (
        PARTITION BY symbol
        ORDER BY tradedate
        MEASURES
          MATCH_NUMBER() AS matchnum,
          A.tradedate AS startdate,
          A.price AS startprice,
          LAST(B.tradedate) AS bottomdate,
          LAST(B.price) AS bottomprice,
          LAST(C.tradedate) AS enddate, -- same as LAST(tradedate)
          LAST(C.price) AS endprice,
          MAX(U.price) AS maxprice -- same as MAX(price)
        ONE ROW PER MATCH -- default
        AFTER MATCH SKIP PAST LAST ROW -- default
        PATTERN (A B+ C+)
        SUBSET U = (A, B, C)
        DEFINE
          -- A defaults to True, matches any row, same as explicitly defining A AS 1 = 1
          B AS B.price < PREV(B.price),
          C AS C.price > PREV(C.price)
      ) AS MR;

    Klauzula PARTITION BY określa, że ​​chcesz obsługiwać każdy symbol giełdowy osobno.

    Klauzula ORDER BY definiuje zamawianie na podstawie daty transakcji.

    Klauzula DEFINE definiuje zmienne wzorca wierszy reprezentujące różne podsekwencje wierszy we wzorcu. W powyższym przykładzie A reprezentuje dowolny wiersz jako punkt początkowy, B reprezentuje podciąg malejących cen (B.cena PREV( C.cena)).

    Klauzula PATTERN używa wyrażeń regularnych do identyfikacji wzorca. W powyższym zapytaniu wzorzec to (A B+ C+), co oznacza (dowolny wiersz, po którym następuje jeden lub więcej wierszy z malejącymi cenami, po których następuje jeden lub więcej wierszy z rosnącymi cenami). Poniżej znajdują się kwantyfikatory wzorców wyrażeń regularnych, których można użyć:

    * — zero (0) or more matches
    + — one (1) or more matches
    ? — no match or one (1) match, optional
    { n } — exactly n matches
    { n, } — n or more matches
    { n, m } — between n and m (inclusive) matches
    { , m } — between zero (0) and m (inclusive) matches
    {- Variable -}, e.g., {- A -} — indicates that matching rows are to be excluded from the output (useful only if ALL ROW PER MATCH specified)
    |, e.g., A | B — alternation
    (), e.g., (A | B) — grouping
    ^, e.g., ^A{1, 3} — start of a row pattern partition
    $, e.g., A{1, 3}$ — end of a row pattern partition 

    Domyślnie kwantyfikatory są zachłanne, ale można je zdefiniować jako niechętne.

    Klauzula SUBSET umożliwia zdefiniowanie nazwanej listy podzbiorów zmiennych.

    Klauzula MEASURES definiuje miary związane ze wzorcem. Obliczenia można stosować do zmiennych szyku i podzbiorów. Funkcja MATCH_NUMBER() przypisuje sekwencyjne liczby całkowite zaczynające się od 1 dla dopasowań w obrębie partycji. Możesz używać operacji takich jak FIRST, LAST, PREV i NEXT, a także obliczeń zbiorczych.

    To zapytanie używa ONE ROW PER MATCH jako wierszy wzorca wierszy na opcję dopasowania. Oznacza to, że tabela wynikowa będzie miała jeden wiersz na dopasowanie wzorca, podobnie jak wynik grupowania. Alternatywą jest WSZYSTKIE WIERSZE NA DOPASOWANIE, w którym chcesz, aby wiersze szczegółów były zwracane dla dopasowania wzorca (przykład, który zostanie przedstawiony wkrótce).

    To zapytanie używa opcji AFTER MATCH SKIP PAST LAST ROW jako funkcji AFTER MATCH . Oznacza to, że po znalezieniu dopasowania chcesz, aby następna próba rozpoczęła się po ostatnim rzędzie bieżącego dopasowania. Istnieją inne alternatywy, takie jak szukanie następnego dopasowania w wierszu po pierwszym wierszu bieżącego dopasowania (SKIP TO NEXT ROW) lub przeskoczenie do pozycji względem zmiennej wzorca wiersza.

    Oto oczekiwany wynik tego zapytania:

    symbol  matchnum  startdate   startprice  bottomdat   bottomprice  enddate     endprice  maxprice
    ------  --------  ----------  ----------  ----------  -----------  ----------  --------  --------
    STOCK1  1         2019-02-13  151.00      2019-02-18  142.00       2019-02-20  152.00    152.00
    STOCK1  2         2019-02-27  154.00      2019-03-04  140.00       2019-03-06  143.00    154.00
    STOCK2  1         2019-02-14  329.00      2019-02-18  325.00       2019-02-20  328.00    329.00
    STOCK2  2         2019-02-21  326.00      2019-02-25  317.00       2019-02-27  325.00    326.00
    STOCK2  3         2019-03-01  324.00      2019-03-05  319.00       2019-03-07  326.00    326.00

    Oto nieco zmodyfikowana wersja zapytania przy użyciu opcji WSZYSTKIE WIERSZE NA MATCH:

    SELECT
      MR.symbol, MR.tradedate, MR.price, MR.matchnum, MR.classy, 
      MR.startdate, MR.startprice, MR.bottomdate, MR.bottomprice,
      MR.enddate, MR.endprice, MR.maxprice
    FROM dbo.Ticker
      MATCH_RECOGNIZE
      (
        PARTITION BY symbol
        ORDER BY tradedate
        MEASURES
          MATCH_NUMBER() AS matchnum,
          CLASSIFIER() AS classy,
          A.tradedate AS startdate,
          A.price AS startprice,
          LAST(B.tradedate) AS bottomdate,
          LAST(B.price) AS bottomprice,
          LAST(C.tradedate) AS enddate,
          LAST(C.price) AS endprice,
          MAX(U.price) AS maxprice
        ALL ROWS PER MATCH
        AFTER MATCH SKIP PAST LAST ROW
        PATTERN (A B+ C+)
        SUBSET U = (A, B, C)
        DEFINE
          B AS B.price < PREV(B.price),
          C AS C.price > PREV(C.price)
      ) AS MR;

    Oto oczekiwany wynik tego zapytania:

    symbol  tradedate   price   matchnum  classy  startdate   startprice bottomdate  bottomprice enddate     endprice   maxprice
    ------  ----------  ------  --------  ------  ----------  ---------- ----------  ----------- ----------  ---------  --------
    STOCK1  2019-02-13  151.00  1         A       2019-02-13  151.00     NULL        NULL        NULL        NULL       151.00
    STOCK1  2019-02-14  148.00  1         B       2019-02-13  151.00     2019-02-14  148.00      NULL        NULL       151.00
    STOCK1  2019-02-15  146.00  1         B       2019-02-13  151.00     2019-02-15  146.00      NULL        NULL       151.00
    STOCK1  2019-02-18  142.00  1         B       2019-02-13  151.00     2019-02-18  142.00      NULL        NULL       151.00
    STOCK1  2019-02-19  144.00  1         C       2019-02-13  151.00     2019-02-18  142.00      2019-02-19  144.00     151.00
    STOCK1  2019-02-20  152.00  1         C       2019-02-13  151.00     2019-02-18  142.00      2019-02-20  152.00     152.00
    STOCK1  2019-02-27  154.00  2         A       2019-02-27  154.00     NULL        NULL        NULL        NULL       154.00
    STOCK1  2019-02-28  153.00  2         B       2019-02-27  154.00     2019-02-28  153.00      NULL        NULL       154.00
    STOCK1  2019-03-01  145.00  2         B       2019-02-27  154.00     2019-03-01  145.00      NULL        NULL       154.00
    STOCK1  2019-03-04  140.00  2         B       2019-02-27  154.00     2019-03-04  140.00      NULL        NULL       154.00
    STOCK1  2019-03-05  142.00  2         C       2019-02-27  154.00     2019-03-04  140.00      2019-03-05  142.00     154.00
    STOCK1  2019-03-06  143.00  2         C       2019-02-27  154.00     2019-03-04  140.00      2019-03-06  143.00     154.00
    STOCK2  2019-02-14  329.00  1         A       2019-02-14  329.00     NULL        NULL        NULL        NULL       329.00
    STOCK2  2019-02-15  326.00  1         B       2019-02-14  329.00     2019-02-15  326.00      NULL        NULL       329.00
    STOCK2  2019-02-18  325.00  1         B       2019-02-14  329.00     2019-02-18  325.00      NULL        NULL       329.00
    STOCK2  2019-02-19  326.00  1         C       2019-02-14  329.00     2019-02-18  325.00      2019-02-19  326.00     329.00
    STOCK2  2019-02-20  328.00  1         C       2019-02-14  329.00     2019-02-18  325.00      2019-02-20  328.00     329.00
    STOCK2  2019-02-21  326.00  2         A       2019-02-21  326.00     NULL        NULL        NULL        NULL       326.00
    STOCK2  2019-02-22  320.00  2         B       2019-02-21  326.00     2019-02-22  320.00      NULL        NULL       326.00
    STOCK2  2019-02-25  317.00  2         B       2019-02-21  326.00     2019-02-25  317.00      NULL        NULL       326.00
    STOCK2  2019-02-26  319.00  2         C       2019-02-21  326.00     2019-02-25  317.00      2019-02-26  319.00     326.00
    STOCK2  2019-02-27  325.00  2         C       2019-02-21  326.00     2019-02-25  317.00      2019-02-27  325.00     326.00
    STOCK2  2019-03-01  324.00  3         A       2019-03-01  324.00     NULL        NULL        NULL        NULL       324.00
    STOCK2  2019-03-04  321.00  3         B       2019-03-01  324.00     2019-03-04  321.00      NULL        NULL       324.00
    STOCK2  2019-03-05  319.00  3         B       2019-03-01  324.00     2019-03-05  319.00      NULL        NULL       324.00
    STOCK2  2019-03-06  322.00  3         C       2019-03-01  324.00     2019-03-05  319.00      2019-03-06  322.00     324.00
    STOCK2  2019-03-07  326.00  3         C       2019-03-01  324.00     2019-03-05  319.00      2019-03-07  326.00     326.00
    
    27 row(s) affected.

    Zwróć uwagę na dodanie klasy miary opartej na funkcji CLASSIFIER. Ta funkcja zwraca ciąg znaków reprezentujący zmienną wzorca wiersza, z którą powiązany jest wiersz wynikowy (w naszym przypadku A, B lub C).

    Funkcja R020, „Rozpoznawanie wzorców wierszy:klauzula WINDOW”

    Właściwość R020 wykorzystuje rozpoznawanie wzorców wierszy jako część klauzuli OVER okna (lub klauzuli WINDOW przy określaniu specyfikacji okna) w celu dalszego ograniczenia ramki okna. Podobnie jak partycja okna ogranicza wiersze wyrażenia tabeli wejściowej (FROM… GDZIE… GRUPUJ WEDŁUG… POSIADAJĄC), a rama okna dodatkowo ogranicza partycję okna, z funkcją R020 dodatkowo ograniczasz pełną ramę okna do zmniejszonej ramki okna wykonanej podciągu wierszy tworzących dopasowanie do wzorca. Oto zapytanie demonstrujące tę funkcję z klauzulą ​​WINDOW, używającą specyfikacji dopasowania wzorców wierszy podobnej do tej użytej w pierwszym zapytaniu w tym artykule:

    SELECT T.symbol, T.tradedate, T.price,
      startdate  OVER W, startprice  OVER W,
      bottomdate OVER W, bottomprice OVER W,
      enddate    OVER W, endprice    OVER W,
      maxprice   OVER W
    FROM dbo.Ticker T
    WINDOW W AS
      (
        PARTITION BY symbol
        ORDER BY tradedate
        MEASURES
          A.tradedate AS startdate,
          A.price AS startprice,
          LAST(B.tradedate) AS bottomdate,
          LAST(B.price) AS bottomprice,
          LAST(C.tradedate) AS enddate,
          LAST(C.price) AS endprice,
          MAX(U.price) AS maxprice
        ROWS BETWEEN CURRENT ROW
                 AND UNBOUNDED FOLLOWING
        AFTER MATCH SKIP PAST LAST ROW
        INITIAL -- pattern must start at first row of full window frame; alternative is SEEK
        PATTERN (A B+ C+)
        SUBSET U = (A, B, C)
        DEFINE
          B AS B.price < PREV(B.price),
          C AS C.price > PREV(C.price)
      );

    W przypadku korzystania z rozpoznawania wzorców wierszy z okienkami, pełna ramka okna musi zaczynać się w bieżącym wierszu. Zwróć uwagę na użycie opcji INITIAL w tym zapytaniu. Ta opcja oznacza, że ​​otrzymasz dopasowanie tylko wtedy, gdy wzór zaczyna się od bieżącego wiersza. Alternatywą jest SEEK, co oznacza, że ​​wyszukiwanie dopasowania rozpoczyna się od bieżącego wiersza, ale jest dozwolone do końca pełnej ramy okna. Tak czy inaczej, jeśli zostanie znalezione dopasowanie, zmniejszona rama okienna składa się tylko z wierszy dopasowanych wzorców, w przeciwnym razie zmniejszona rama okienna jest pusta. Szukane jest tylko jedno dopasowanie wzorca wiersza na pełną ramkę okna.

    Zauważ na liście SELECT zapytania, że ​​możesz zwrócić miary zdefiniowane w klauzuli MEASURES, obliczone na W, który jest zmniejszoną ramką okna.

    Przypomnij wynik pierwszego zapytania w tym artykule, używając rozpoznawania wzorców wierszy w klauzuli FROM, z opcją ONE ROW PER MATCH:

    symbol  matchnum  startdate   startprice  bottomdat   bottomprice  enddate     endprice  maxprice
    ------  --------  ----------  ----------  ----------  -----------  ----------  --------  --------
    STOCK1  1         2019-02-13  151.00      2019-02-18  142.00       2019-02-20  152.00    152.00
    STOCK1  2         2019-02-27  154.00      2019-03-04  140.00       2019-03-06  143.00    154.00
    STOCK2  1         2019-02-14  329.00      2019-02-18  325.00       2019-02-20  328.00    329.00
    STOCK2  2         2019-02-21  326.00      2019-02-25  317.00       2019-02-27  325.00    326.00
    STOCK2  3         2019-03-01  324.00      2019-03-05  319.00       2019-03-07  326.00    326.00

    Oto oczekiwany wynik naszego ostatniego zapytania przy użyciu rozpoznawania wzorców wierszy w klauzuli WINDOW:

    symbol  tradedate   price   startdate   startprice bottomdate  bottomprice enddate     endprice  maxprice
    ------  ----------  ------  ----------  ---------- ----------  ----------- ----------  --------  --------
    STOCK1  2019-02-12  150.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-13  151.00  2019-02-13  151.00     2019-02-18  142.00      2019-02-20  152.00    152.00
    STOCK1  2019-02-14  148.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-15  146.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-18  142.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-19  144.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-20  152.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-21  152.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-22  153.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-25  154.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-26  154.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-02-27  154.00  2019-02-27  154.00     2019-03-04  140.00      2019-03-06  143.00    154.00
    STOCK1  2019-02-28  153.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-01  145.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-04  140.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-05  142.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-06  143.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-07  142.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-08  140.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK1  2019-03-11  138.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-12  330.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-13  329.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-14  329.00  2019-02-14  329.00     2019-02-18  325.00      2019-02-20  328.00    329.00
    STOCK2  2019-02-15  326.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-18  325.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-19  326.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-20  328.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-21  326.00  2019-02-21  326.00     2019-02-25  317.00      2019-02-27  325.00    326.00
    STOCK2  2019-02-22  320.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-25  317.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-26  319.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-27  325.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-02-28  322.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-01  324.00  2019-03-01  324.00     2019-03-05  319.00      2019-03-07  326.00    326.00
    STOCK2  2019-03-04  321.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-05  319.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-06  322.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-07  326.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-08  326.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    STOCK2  2019-03-11  324.00  NULL        NULL       NULL        NULL        NULL        NULL      NULL
    
    40 row(s) affected.

    Zauważ, że na wyjściu otrzymujesz wszystkie szczegółowe wiersze, a tam, gdzie zaczyna się dopasowanie wzorca, otrzymujesz wynik żądanych miar wzorca wiersza w stosunku do zmniejszonej ramki okna.

    Oddaj swój głos

    Jest całkowicie zrozumiałe, że dodanie funkcji do T-SQL przez Microsoft — zwłaszcza tak znaczącej — jest dość znaczącą inwestycją. Ale to, co jest wspaniałe w funkcjach dodanych do T-SQL, to to, że pozostają tam na zawsze. Istnieje ogromna społeczność głodna ulepszeń T-SQL, takich jak ta.

    Jeśli uważasz, że rozpoznawanie wzorców wierszy jest ważnym dodatkiem do SQL Server, upewnij się, że oddajesz swój głos. Ponadto firma Microsoft jest bardziej skłonna do nadania priorytetu proponowanej funkcji, jeśli zna klientów i przypadki użycia, które mogą z niej skorzystać, oraz jeśli w tej chwili tacy klienci korzystają z innych produktów lub bardziej złożonych rozwiązań. Jeśli Ty lub Twoi klienci uważacie, że RPR jest dla Was korzystne i macie przypadki użycia, którymi możecie się podzielić, pamiętajcie, aby dodać komentarze do elementu opinii i powiadomić o tym firmę Microsoft.


    1. Database
    2.   
    3. Mysql
    4.   
    5. Oracle
    6.   
    7. Sqlserver
    8.   
    9. PostgreSQL
    10.   
    11. Access
    12.   
    13. SQLite
    14.   
    15. MariaDB
    1. Sprawa dla ZAMIAST wyzwalaczy – część 1

    2. SQL ALTER TABLE dla początkujących

    3. KLUCZ OBCY SQL

    4. Wzorzec danych referencyjnych:rozszerzalny i elastyczny

    5. Zaawansowane monitorowanie i zarządzanie bazą danych dla TimescaleDB