sql >> Database >  >> RDS >> Database

Rijpatroonherkenning in SQL

De ISO/IEC 9075:2016-standaard, of kortweg SQL:2016, introduceert ondersteuning voor een diepgaand concept genaamd Row Pattern Recognition (RPR) in SQL. Ik heb een suggestie gepost om SQL Server te verbeteren door ondersteuning voor RPR in T-SQL toe te voegen, maar ik was vrij beperkt in de ruimte die ik had om de feedback te geven. Het doel van dit artikel is om meer details over het voorstel te geven, en hopelijk zult u overtuigd zijn van het belang ervan en uw stem toevoegen.

Achtergrond

Vergelijkbaar met het gebruik van reguliere expressies om patronen in een string te identificeren, gebruik je met RPR reguliere expressies om patronen in een reeks rijen te identificeren. Voor elke patroonovereenkomst kunt u ofwel een samenvattende rij retourneren, zoals bij groeperen, of de gedetailleerde rijen, met berekende maten tegen subreeksen van de overeenkomst. RPR heeft onbeperkte praktische toepassingen, waaronder het identificeren van patronen in beursactiviteit (zowel geldige patronen met handelswaarde als mogelijk illegale of verdachte patronen), het afhandelen van tijdreeksen, fraudedetectie, materiaalbehandeling, verzendtoepassingen, DNA-sequencing, hiaten en eilanden, top N per groep, en vele anderen.

Voor mij is RPR de volgende stap in de evolutie van vensterfuncties, met een hoger niveau van verfijning en uitgebreide bruikbaarheid. Als je denkt dat vensterfuncties diepgaand en nuttig zijn, gaat RPR echt je noodle bakken. Net als bij vensterfuncties ondersteunt RPR partitioneren en ordenen. Meestal zoekt u naar patroonovereenkomsten binnen elke partitie afzonderlijk, op basis van de aangegeven volgorde. Ook vergelijkbaar met vensterfuncties, leent RPR zich voor goede optimalisatie, met de mogelijkheid om te vertrouwen op indexvolgorde om te voorkomen dat de gegevens worden gesorteerd.

U vindt de dekking van RPR, inclusief geïllustreerde voorbeelden, in een technisch rapport van 90 pagina's ISO/IEC TR 19075-5 (gratis beschikbaar).

U kunt het ook vinden als onderdeel van het document ISO/IEC 9075-2:2016, Informatietechnologie — Databasetalen — SQL — Deel 2:Foundation (SQL/Foundation) (beschikbaar voor aankoop).

De SQL:2016-standaard biedt twee belangrijke RPR-gerelateerde functies:

  • Functie R010, "Rijpatroonherkenning:FROM-clausule"
  • Functie R020, "Rijpatroonherkenning:WINDOW-clausule"

De standaard vermeldt ook functie R030, "Rijpatroonherkenning:volledige geaggregeerde ondersteuning", zonder welke geaggregeerde functies DISTINCT of niet mogen specificeren.

Tot nu toe is Oracle het enige platform dat ik ken van die geïmplementeerde functie R010. Ik ken nog geen platform dat R020 heeft geïmplementeerd.

Functie R010, "Rijpatroonherkenning:FROM-clausule"

Functie R010 definieert een clausule/tabeloperator genaamd MATCH_RECOGNIZE, die u gebruikt in de FROM-clausule. De invoer is een tabel of tabeluitdrukking en de uitvoer is een virtuele tabel. De context is vergelijkbaar met die van andere tabeloperatoren zoals JOIN, APPLY, PIVOT en UNPIVOT. Hier is de syntaxis van een zoekopdracht die deze functie gebruikt:

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

Stel dat u een tabel dbo.Ticker krijgt, met kolommen symbool, handelsdatum en prijs, als voorbeeld aangepast aan het bovengenoemde technische rapport. Gebruik de volgende code om de tabel te maken, vul deze met enkele voorbeeldgegevens en bevraag deze:

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;

Deze code genereert de volgende uitvoer:

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.

De volgende zoekopdracht identificeert patronen die V-vormen in de aandelenkoers vertegenwoordigen (een periode met een strikt dalende prijs gevolgd door een periode met een strikt stijgende prijs), met EEN RIJ PER WEDSTRIJD als de rijpatroonrijen per wedstrijd optie:

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;

De clausule PARTITION BY definieert dat u elk aandelensymbool afzonderlijk wilt behandelen.

De ORDER BY-clausule definieert bestellen op basis van handelsdatum.

De DEFINE-component definieert rijpatroonvariabelen die de verschillende subreeksen van rijen in het patroon vertegenwoordigen. In het bovenstaande voorbeeld stelt A een willekeurige rij voor als startpunt, B staat voor een vervolg van dalende prijzen (B.prijs PREV( C.prijs)).

De PATTERN-component gebruikt reguliere expressies om een ​​patroon te identificeren. In de bovenstaande query is het patroon (A B+ C+), wat betekent (elke rij, gevolgd door een of meer rijen met dalende prijzen, gevolgd door een of meer rijen met stijgende prijzen). Hieronder volgen de kwantificatoren van reguliere expressiepatronen die u kunt gebruiken:

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

Standaard zijn de kwantoren hebzuchtig, maar je kunt ze definiëren om terughoudend te zijn.

Met de SUBSET-component kunt u een benoemde subset-lijst met variabelen definiëren.

De clausule MEASURES definieert maatregelen die verband houden met het patroon. U kunt berekeningen toepassen op patroonvariabelen en op subsets. De functie MATCH_NUMBER() wijst opeenvolgende gehele getallen toe die beginnen met 1 voor de overeenkomsten binnen de partitie. U kunt bewerkingen gebruiken zoals EERSTE, LAATSTE, PREV en VOLGENDE, evenals geaggregeerde berekeningen.

Deze query gebruikt EEN RIJ PER MATCH als optie voor rijpatroonrijen per overeenkomst. Dit betekent dat de resultatentabel één rij per patroonovereenkomst heeft, vergelijkbaar met het resultaat van groeperen. Het alternatief is ALLE RIJEN PER WEDSTRIJD waarbij u de detailrijen wilt retourneren per patroonovereenkomst (voorbeeld volgt binnenkort).

Deze query gebruikt AFTER MATCH SKIP PAST LAST ROW als de AFTER MATCH . Dit betekent dat als er eenmaal een overeenkomst is gevonden, u wilt dat de volgende poging wordt gestart na de laatste rij van de huidige overeenkomst. Er zijn andere alternatieven, zoals zoeken naar de volgende overeenkomst in de rij die volgt op de eerste rij van de huidige overeenkomst (SKIP TO NEXT ROW), of naar een positie gaan ten opzichte van een rijpatroonvariabele.

Dit is de verwachte output van deze zoekopdracht:

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

Hier is een licht gewijzigde versie van de zoekopdracht met de optie ALLE RIJEN PER WEDSTRIJD:

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;

Dit is de verwachte output van deze zoekopdracht:

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.

Let op de toevoeging van de maat classy op basis van de functie CLASSIFIER. Deze functie retourneert een tekenreeks die de rijpatroonvariabele vertegenwoordigt waaraan de resultaatrij is gekoppeld (in ons geval A, B of C).

Functie R020, "Rijpatroonherkenning:WINDOW-clausule"

Functie R020 gebruikt rijpatroonherkenning als onderdeel van de OVER-clausule (of WINDOW-clausule bij het benoemen van een vensterspecificatie) om een ​​raamkozijn verder te beperken. Net zoals de vensterpartitie de rijen van de invoertabeluitdrukking beperkt (VAN... WAAR... GROUP BY... HAVING), en het raamkozijn de raampartitie verder beperkt, beperkt u met functie R020 het volledige raamkozijn verder tot een verkleind raamkozijn gemaakt van de opeenvolging van rijen die de patroonovereenkomst vormen. Hier is een zoekopdracht die deze functie demonstreert met de WINDOW-clausule, met een vergelijkbare specificatie voor rijpatroonovereenkomst als die gebruikt in de eerste zoekopdracht in dit artikel:

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

Bij gebruik van rijpatroonherkenning met windowing moet het volledige raamkozijn beginnen bij de huidige rij. Let op het gebruik van de INITIAL-optie in deze query. Deze optie betekent dat u alleen een overeenkomst krijgt als het patroon begint met de huidige rij. Het alternatief is SEEK, wat inhoudt dat het zoeken naar een overeenkomst begint met de huidige rij, maar is toegestaan ​​tot het einde van het volledige raamkozijn. Hoe dan ook, als een overeenkomst wordt gevonden, bestaat het verkleinde raamkozijn alleen uit de patroonovereenkomstrijen, anders is het verkleinde raamkozijn leeg. Er wordt slechts één rijpatroonovereenkomst per volledig raamkozijn gezocht.

Merk op in de SELECT-lijst van de query dat u metingen kunt retourneren die zijn gedefinieerd in de MEASURES-component, berekend over W, wat het verkleinde raamkozijn is.

Roep het resultaat op van de eerste query in dit artikel, met behulp van rijpatroonherkenning in de FROM-component, met de ONE ROW PER MATCH-optie:

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

Dit is de verwachte uitvoer van onze laatste zoekopdracht, met behulp van rijpatroonherkenning in de WINDOW-clausule:

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.

Merk op dat u alle gedetailleerde rijen in de uitvoer krijgt, en waar een patroonovereenkomst begint, krijgt u het resultaat van de gevraagde rijpatroonmetingen tegen het verkleinde raamkozijn.

Breng uw stem uit

Het is volkomen duidelijk dat het voor Microsoft een behoorlijk aanzienlijke investering is om een ​​functie aan T-SQL toe te voegen, vooral zo'n substantiële. Maar wat zo geweldig is aan functies die aan T-SQL worden toegevoegd, is dat ze daar vrijwel voor altijd blijven. Er is een enorme gemeenschap die hongert naar T-SQL-verbeteringen zoals deze.

Als je vindt dat rijpatroonherkenning een belangrijke toevoeging is aan SQL Server, breng dan zeker je stem uit. Microsoft zal ook eerder prioriteit geven aan een voorgestelde functie als ze klanten kennen en cases gebruiken die er baat bij kunnen hebben, en dat dergelijke klanten op dit moment andere producten of complexere oplossingen gebruiken. Als u of uw klanten RPR als gunstig voor u beschouwen en gebruiksscenario's hebben die u kunt delen, zorg er dan voor dat u opmerkingen toevoegt aan het feedbackitem en laat het Microsoft weten.


  1. SSL of TLS inschakelen in Oracle Apps R12

  2. Hoe hernoem je een primaire sleutel in Oracle zodat deze opnieuw kan worden gebruikt?

  3. Waarom krijg ik OutOfRange Exception in GetOrdinal Function van dit CLOB-veld?

  4. MySQL gebruiken met Oracle Heterogene Services