sql >> Database teknologi >  >> RDS >> Sqlserver

Oprettelse af grupper af på hinanden følgende dage, der opfylder et givet kriterium

I dette svar antager jeg, at "id"-feltet nummererer rækkerne fortløbende, når de sorteres efter stigende dato, ligesom det gør i eksempeldataene. (Sådan en kolonne kan oprettes, hvis den ikke findes).

Dette er et eksempel på en teknik beskrevet her og her .

1) Slut tabellen til sig selv på tilstødende "id"-værdier. Dette parrer tilstødende rækker. Vælg rækker, hvor feltet "tildeling" er ændret. Gem resultatet i en midlertidig tabel, og hold også et løbende indeks.

SET @idx =0;CREATE MIDLERTIDIG TABEL BOundariesSELECT (@idx :=@idx + 1) AS idx, a1.date AS prev_end, a2.date AS next_start, a1.allocation as allocationFROM allocations a1JOIN allocations a2ON (a2.id =a1.id + 1)WHERE a1.allocation !=a2.allocation; 

Dette giver dig en tabel med "slutningen af ​​den forrige periode", "begyndelsen af ​​den næste periode" og "værdien af ​​'allokering' i den foregående periode" i hver række:

+------+-------------+------------+-------- --+| idx | prev_end | næste_start | tildeling |+------+-------------+------------+-----+| 1 | 01-01-2012 | 2012-01-02 | 0 || 2 | 2012-01-02 | 03-01-2012 | 2 || 3 | 2012-01-05 | 2012-01-06 | 0 |+------+-----------------+-----+

2) Vi skal bruge starten og slutningen af ​​hver periode i samme række, så vi skal kombinere tilstødende rækker igen. Gør dette ved at oprette en anden midlertidig tabel som grænser men har en idx felt 1 større:

+------+------------+------------+| idx | prev_end | næste_start |+------+------------+------------+| 2 | 01-01-2012 | 2012-01-02 || 3 | 2012-01-02 | 03-01-2012 || 4 | 2012-01-05 | 2012-01-06 |+------+------------+------------+

Deltag nu på idx felt og vi får svaret:

SELECT boundaries2.next_start AS start, boundaries.prev_end AS end, allocationFROM boundariesJOIN boundaries2USING(idx);+------------+---------- --+------------+| start | ende | tildeling |+------------+------------+------------+| 2012-01-02 | 2012-01-02 | 2 || 03-01-2012 | 2012-01-05 | 0 |+------------+-------------+------------+ 

** Bemærk, at dette svar får de "interne" perioder korrekt, men savner de to "kantperioder", hvor allokering =0 i begyndelsen og allokering =5 i slutningen. Disse kan trækkes ind ved hjælp af UNION klausuler, men jeg ønskede at præsentere kerneideen uden den komplikation.



  1. Råd om SQL Server-ydelse fra Brent Ozar og Pinal Dave

  2. Fejlfinding, der løber tør for arbejdstråde

  3. Sådan skriver du udvalgte erklæringer

  4. Nogen gode relationsdatabase tutorials?