SQL
Window-functies
Zoeken…
Het toevoegen van het totale aantal geselecteerde rijen aan elke rij
SELECT your_columns, COUNT(*) OVER() as Ttl_Rows FROM your_data_set
ID kaart | naam | Ttl_Rows |
---|---|---|
1 | voorbeeld | 5 |
2 | foo | 5 |
3 | bar | 5 |
4 | baz | 5 |
5 | quux | 5 |
In plaats van twee query's te gebruiken om een telling dan de regel te krijgen, kunt u een aggregatie als vensterfunctie gebruiken en het volledige resultaatset als venster gebruiken.
Dit kan worden gebruikt als basis voor verdere berekening zonder de complexiteit van extra self-joins.
Een vlag instellen als andere rijen een gemeenschappelijke eigenschap hebben
Laten we zeggen dat ik deze gegevens heb:
Tafel items
ID kaart | naam | label |
---|---|---|
1 | voorbeeld | unique_tag |
2 | foo | gemakkelijk |
42 | bar | gemakkelijk |
3 | baz | Hallo |
51 | quux | wereld |
Ik wil graag al die regels krijgen en weten of een tag door andere regels wordt gebruikt
SELECT id, name, tag, COUNT(*) OVER (PARTITION BY tag) > 1 AS flag FROM items
Het resultaat zal zijn:
ID kaart | naam | label | vlag |
---|---|---|---|
1 | voorbeeld | unique_tag | vals |
2 | foo | gemakkelijk | waar |
42 | bar | gemakkelijk | waar |
3 | baz | Hallo | vals |
51 | quux | wereld | vals |
Als uw database geen OVER en PARTITION heeft, kunt u dit gebruiken om hetzelfde resultaat te produceren:
SELECT id, name, tag, (SELECT COUNT(tag) FROM items B WHERE tag = A.tag) > 1 AS flag FROM items A
Een lopend totaal krijgen
Gezien deze gegevens:
datum | bedrag |
---|---|
2016/03/12 | 200 |
2016/03/11 | -50 |
2016/03/14 | 100 |
2016/03/15 | 100 |
2016/03/10 | -250 |
SELECT date, amount, SUM(amount) OVER (ORDER BY date ASC) AS running
FROM operations
ORDER BY date ASC
zal je geven
datum | bedrag | rennen |
---|---|---|
2016/03/10 | -250 | -250 |
2016/03/11 | -50 | -300 |
2016/03/12 | 200 | -100 |
2016/03/14 | 100 | 0 |
2016/03/15 | 100 | -100 |
Verkrijg de N meest recente rijen over meerdere groepen
Gezien deze gegevens
Gebruikersnaam | Einddatum |
---|---|
1 | 2016/07/20 |
1 | 2016/07/21 |
2 | 2016/07/20 |
2 | 2016/07/21 |
2 | 2016/07/22 |
;with CTE as
(SELECT *,
ROW_NUMBER() OVER (PARTITION BY User_ID
ORDER BY Completion_Date DESC) Row_Num
FROM Data)
SELECT * FORM CTE WHERE Row_Num <= n
Met n = 1 krijg je de meest recente rij per user_id
:
Gebruikersnaam | Einddatum | rij_getal |
---|---|---|
1 | 2016/07/21 | 1 |
2 | 2016/07/22 | 1 |
"Out-of-sequence" -records zoeken met de functie LAG ()
Gezien deze voorbeeldgegevens:
ID kaart | TOESTAND | STATUS_TIME | STATUS_BY |
---|---|---|---|
1 | EEN | 2016-09-28-19.47.52.501398 | USER_1 |
3 | EEN | 2016-09-28-19.47.52.501511 | USER_2 |
1 | DRIE | 2016-09-28-19.47.52.501517 | USER_3 |
3 | TWEE | 2016-09-28-19.47.52.501521 | USER_2 |
3 | DRIE | 2016-09-28-19.47.52.501524 | USER_4 |
Items geïdentificeerd door ID
waarden moeten in volgorde van STATUS
'EEN' naar 'TWEE' naar 'DRIE' gaan, zonder statussen over te slaan. Het probleem is om gebruikerswaarden ( STATUS_BY
) te vinden die de regel overtreden en onmiddellijk van 'EEN' naar 'DRIE' gaan.
De analytische functie LAG()
helpt het probleem op te lossen door voor elke rij de waarde in de vorige rij te retourneren:
SELECT * FROM (
SELECT
t.*,
LAG(status) OVER (PARTITION BY id ORDER BY status_time) AS prev_status
FROM test t
) t1 WHERE status = 'THREE' AND prev_status != 'TWO'
Als uw database geen LAG () heeft, kunt u dit gebruiken om hetzelfde resultaat te produceren:
SELECT A.id, A.status, B.status as prev_status, A.status_time, B.status_time as prev_status_time
FROM Data A, Data B
WHERE A.id = B.id
AND B.status_time = (SELECT MAX(status_time) FROM Data where status_time < A.status_time and id = A.id)
AND A.status = 'THREE' AND NOT B.status = 'TWO'