Sök…


Lägga till de totala raderna som valts till varje rad

SELECT your_columns, COUNT(*) OVER() as Ttl_Rows FROM your_data_set
id namn Ttl_Rows
1 exempel 5
2 foo 5
3 bar 5
4 baz 5
5 quux 5

I stället för att använda två frågor för att få en räkning sedan linjen, kan du använda ett aggregerat som fönsterfunktion och använda hela resultatuppsättningen som fönster.
Detta kan användas som bas för vidare beräkning utan komplexiteten hos extra självförbindelser.

Ställa in en flagga om andra rader har en gemensam egenskap

Låt oss säga att jag har dessa data:

Tabellobjekt

id namn märka
1 exempel unique_tag
2 foo enkel
42 bar enkel
3 baz Hej
51 quux värld

Jag skulle vilja få alla dessa rader och veta om en tagg används av andra linjer

SELECT id, name, tag, COUNT(*) OVER (PARTITION BY tag) > 1 AS flag FROM items

Resultatet blir:

id namn märka flagga
1 exempel unique_tag falsk
2 foo enkel Sann
42 bar enkel Sann
3 baz Hej falsk
51 quux värld falsk

Om din databas inte har OVER och PARTITION kan du använda den här för att producera samma resultat:

SELECT id, name, tag, (SELECT COUNT(tag) FROM items B WHERE tag = A.tag) > 1 AS flag FROM items A

Få ett löpande totalt

Med tanke på dessa uppgifter:

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

kommer att ge dig

datum belopp löpning
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

Få de senaste raderna över flera grupper

Med tanke på dessa uppgifter

Användar ID COMPLETION_DATE
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

Med n = 1 får du den senaste raden per user_id :

Användar ID COMPLETION_DATE ROW_NUM
1 2016/07/21 1
2 2016/07/22 1

Hitta "out-of-sequence" -poster med funktionen LAG ()

Med tanke på dessa exempeldata:

ID STATUS STATUS_TIME STATUS_BY
1 ETT 2016-09-28-19.47.52.501398 USER_1s
3 ETT 2016-09-28-19.47.52.501511 USER_2
1 TRE 2016-09-28-19.47.52.501517 USER_3
3 TVÅ 2016-09-28-19.47.52.501521 USER_2
3 TRE 2016-09-28-19.47.52.501524 USER_4

Objekt identifierade med ID värden måste flytta från STATUS 'EN' till 'Två' till 'TRE' i följd, utan att hoppa över statuser. Problemet är att hitta användare ( STATUS_BY ) STATUS_BY som bryter mot regeln och flyttar från 'ONE' omedelbart till 'THREE'.

LAG() hjälper till att lösa problemet genom att för varje rad returnera värdet i föregående rad:

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'

Om din databas inte har LAG () kan du använda den här för att producera samma resultat:

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'


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow