Przypisane dni robocze - jak wykluczyć daty?

0

Cześć!
Mam taki problem, który staram się od jakiegoś czasu rozwiązać:

  1. Dwie kolumny:
    a) Data - wszystkie dni kalendarzowe,
    b) Wartość.

Do tego, left joinem dopisuję daty, które zamieniają dni kalendarzowe na dni robocze (przygotowany kalendarz na wiele lat do przodu). Czyli np. do 15 i 16 czerwca dopisuję 14, itd.

Teraz potrzebuję, żeby suma dla takich dat jak 14 czerwiec nie była z 3 dni, tylko z jednego (w najnowszego dnia kalendarzowego).

Nie wiem czy wytłumaczyłem zrozumiale - w razie czego doprecyzuję.

Jak to rozwiązać?

1

Nie mam pojecia co chcesz osiągnąć. Pokaż kawałek danych i jakiegoś SQLa.

0

W Excelu załączam przykład co chcę osiągnąć.

Chyba wpadłem na jeden z pomysłów, ale wydaje mi się, że mało wydajny -
robię left joina podzapytania z kalendarza (select PDR,max(Data) from kalendarz) i pomijam nulle. Może jest wydajniejsze rozwiązanie?

1

RANK() w sqllite powinien dzialac bez problemu ;)

update -> https://sqliteonline.com/#fiddle-5d0a41fd98b71mzxjx3bbf2y

SET DATEFORMAT DMY;
DECLARE @dane TABLE
    (
        dzien DATETIME ,
        stan MONEY
    );
DECLARE @kalendarz TABLE
    (
        dzien DATETIME ,
        dzien_roboczy DATETIME
    );
INSERT INTO @kalendarz
VALUES ( '29/04/2019', '29/04/2019' ) ,
       ( '30/04/2019', '30/04/2019' ) ,
       ( '01/05/2019', '02/05/2019' ) ,
       ( '02/05/2019', '02/05/2019' ) ,
       ( '03/05/2019', '02/05/2019' ) ,
       ( '04/05/2019', '02/05/2019' ) ,
       ( '05/05/2019', '02/05/2019' ) ,
       ( '06/05/2019', '06/05/2019' ) ,
       ( '07/05/2019', '07/05/2019' );


INSERT INTO @dane
VALUES ( '29/04/2019', 795.29 ) ,
       ( '30/04/2019', 117.44 ) ,
       ( '01/05/2019', 400.45 ) ,
       ( '02/05/2019', 391.09 ) ,
       ( '03/05/2019', 197.55 ) ,
       ( '04/05/2019', 357.61 ) ,
       ( '05/05/2019', 168.88 ) ,
       ( '06/05/2019', 930.18 ) ,
       ( '07/05/2019', 826.36 );

SELECT t.dzien ,
       t.stan ,
       t.dzien_roboczy
FROM   (   SELECT d.dzien ,
                  d.stan ,
                  k.dzien_roboczy ,
                  RANK() OVER ( PARTITION BY k.dzien_roboczy
                                ORDER BY d.dzien DESC ) score
           FROM   @dane d
                  LEFT JOIN @kalendarz k ON k.dzien = d.dzien ) AS t
WHERE  t.score = 1;

screenshot-20190619151054.png

0

Dzięki!
Pomysł bardzo fajny, ale coś nie chce mi działać na SQLite. Nie wiem, czy coś źle robię, czy po prostu w tym środowisku działa to jakoś inaczej?

1

https://sqliteonline.com/#fiddle-5d0a4d8098b73mzxjx3d2kyi

SELECT dzien ,
       stan ,
       dzien_roboczy
FROM   (   SELECT * ,
                  RANK() OVER wscore [Score]
           FROM   dane d
                  LEFT JOIN kalendarz k ON d.dzien = k.dzien

				  WINDOW wscore AS (PARTITION BY k.dzien_roboczy ORDER BY d.dzien DESC) 
                           ) AS t
WHERE  t.Score = 1;
 

nie jestem specem od sqlite ale moze tak ??

0

Próbowałem, ale to też nie chce mi zadziałać :|

Teoretycznie powinno śmigać:
http://www.sqlitetutorial.net/sqlite-window-functions/sqlite-rank/

0

Trochę nie kumam - może dlatego, że nigdy nie używałem CTE.

Teoretycznie można użyć samego MAXa dla całości danych - tak też próbowałem, ale bardzo wolno mi to chodzi.

A może do całości danych zrobić INNER JOIN

select
dzien_roboczy,
max(dzien)

from
kalendarz

group by
dzien_roboczy

?

0
WITH  cte (
    dzien,
    dzien_roboczy
)
AS (
    SELECT MAX(k.dzien) dzien,
           dzien_roboczy
      FROM kalendarz k
     GROUP BY k.dzien_roboczy
)
SELECT d.dzien,
       d.stan,
       c.dzien_roboczy
  FROM cte c
      inner JOIN
       dane d ON d.dzien = c.dzien
       order by d.dzien

Dane dla 3 lat

screenshot-20190621142411.png

A tak wygladaj moje tabele

CREATE TABLE dane (
    dzien DATETIME PRIMARY KEY
                   UNIQUE,
    stan  MONEY
);

CREATE TABLE kalendarz (
    dzien         DATETIME PRIMARY KEY
                           UNIQUE,
    dzien_roboczy DATETIME
);

1

Ruszyło, dzięki za pomoc! Na pewno nie jest to hiperoptymalne rozwiązanie - będę jeszcze myślał. Uruchomiłem też RANK(), ale wolno działa :( Nawet po tabelach poindeksowanych.

"SQLiteStudio 3.2.1 ma wersję SQLite 3.24.0, gdzie nie było jeszcze RANK(). Dodanie RANK() jest w planach dla SQLiteStudio 3.3.0.

Można to obejść - ze strony SQLite.org pobrać plik dll: https://sqlite.org/2019/sqlite-dll-win32-x86-3280000.zip i podmienić go z tym w folderze instalacji SQLiteStudio (aplikacja musi być wtedy zamknięta).

SQLiteStudio nadal będzie podkreślało błąd składni w edytorze SQL, ale po wywołaniu zapytania powinno się ono wykonać poprawnie."

1 użytkowników online, w tym zalogowanych: 0, gości: 1