Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Pouze tento týden sleva až 80 % na e-learning týkající se Swiftu. Zároveň využij výhodnou slevovou akci až 30 % zdarma při nákupu e-learningu - více informací.
discount 30 + hiring
Avatar
c.bohumil
Člen
Avatar
c.bohumil:24. února 21:11

Mám data po v 15minutvých intervalech a jde mi o to sloučit je do 60min.

Abych to měl tak jak potřebuji musí se seskupit datum = 0:15+0:30+0:4­5+01:00 do datumu kde začíná 0:15

2021-01-31 21:00 1
2021-01-31 21:15 229
2021-01-31 21:30 255
2021-01-31 21:45 391
2021-01-31 22:00 471
2021-01-31 22:15 803
2021-01-31 22:30 1019
2021-01-31 22:45 1040
2021-01-31 23:00 1061

2021-01-31
     23:15         1187
2021-01-31      23:30   1187
2021-01-31      23:45   1292
2021-02-01      0:00    1342

2021-02-01 0:15 1394
2021-02-01 0:30 1427
2021-02-01 0:45 1461
2021-02-01 1:00 1477
2021-02-01 1:15 1512
2021-02-01 1:30 1483

Zkusil jsem: select
Datum
,left(right('0000' + convert(float(4), t.čas),4), 2) + ':00' as Čas
, sum(t.kw) as kw

from [dbo].[Test5] t

group by t.Datum

,left(right('0000' + convert(float(4), t.čas), 4), 2) + ':00'

ORDER BY
Datum ASC, Čas ASC OFFSET 0 ROWS

 
Odpovědět
24. února 21:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25. února 8:23

Pokud je vzorec na separaci minut a dnu slozity, tak bys si udela pomocnou tabulku

tabulka: id [integer], date(rok-den-hodina-00) [datetime], minuta [integer]

Kde pro minutu=0 bych ubral hodina-1
Zgrupoval to podle minut.
A left joinem pridal vse o radku_id, co tam jeste chci mit.

A zapomnel jsi teda zminit, ze se jedna o MS-SQL. Ale treba se mi neco podari vygooglovat...

DATEPART(minute, t.čas) -- 0 az 59, to potrebujes na zjisteni, zda posunout o hodinu nebo ne (0 posouvas, jinak ne)

DateAdd(mi, -(DatePart(mi, t.čas))+15, t.čas) -- vytahnes minuty a odectes je a prictes 15 min, ziskas rrrr-mm-dd hh:15:ms.mms podle ktereho to muzes grupovat
Editováno 25. února 8:25
 
Nahoru Odpovědět
25. února 8:23
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25. února 8:33

Blbe je, kdyby tam ta 15 min hodnota nebyla, tak by tam bylo 15 min. Ale, to by slo taky resit. Pseudokod

m = DATEPART(minute, t.čas) -- vyberes minuty
if (m<15) {m=60+m} -- tem s nulou das max hodnotu
MIN(m) -- vyberes minimum pri grupovani
DateAdd(mi, -(DatePart(mi, t.čas))+m, t.čas) -- a pak to pridas do toho casu,
-- ze ktereho nasledne separujes, co potrebujes, na to asi ma msql nejakou funkci jako date fotmat nebo tak.
 
Nahoru Odpovědět
25. února 8:33
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:25. února 9:20

Asi nejak takhle

SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minute,Datum) in (15,30,45) THEN DATEPART(hour,Datum) + 1
        ELSE DATEPART(hour,Datum)
END as Hodina
, sum(t.kw) as kw
from [dbo].[Test5] t
group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minute,Datum) in (15,30,45) THEN DATEPART(hour,Datum) + 1
        ELSE DATEPART(hour,Datum)
END
ORDER BY 1,2
 
Nahoru Odpovědět
25. února 9:20
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25. února 10:54

no, jenze ten posun o hodinu muze znamenat i posun celeho dne, mesice ci roku, zmena hodnoty "date", v takovem pripade `GROUP BY CAST(Datum as date) ` bude grupovat chybne se starym datum. Ale chapu, proc to tam mas, pro urychleni grupovani. Proto bych sel do pomocne tabulky a nad ni az provadel grupovani.

 
Nahoru Odpovědět
25. února 10:54
Avatar
Petan
Člen
Avatar
Odpovídá na Peter Mlich
Petan:25. února 11:56

Nemuze, datum se nemeni jenom cas muze byt 1 az 24 hodin
kdyz 0 az 23 tak misto case jenom DATEPART(hour,Da­tum) as Hodina

 
Nahoru Odpovědět
25. února 11:56
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:25. února 13:12

Uplne to nechapu. Uvedu priklad.

seskupit datum = 0:15+0:30+0:45+01:00

from
    [dbo].[Test5] t
group by
    CAST(Datum as date),

Tahle cast ti preci zgrupuje vse, co ma stejne datum rrrr-mm-dd.
A az nasledne to tridis pres CASE, ne?
Coz je sice super, ale zgrupuje to

2022-02-25 23:00
2022-02-25 23:15
2022-02-25 23:30
2022-02-25 23:45

jenze od chce sloucit

------ 2022-02-25 23:00 --------- nee
2022-02-25 23:15
2022-02-25 23:30
2022-02-25 23:45
2022-02-26 00:00

 
Nahoru Odpovědět
25. února 13:12
Avatar
c.bohumil
Člen
Avatar
c.bohumil:25. února 16:36
SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minuteas) in (15,30,45,00) THEN DATEPART(houras) +1
        ELSE DATEPART(hour,Datum)
END as Hodina
, sum(kW)/4 as kW


from [dbo].[Test_6]

group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minuteas) in (15,30,45,00) THEN DATEPART(houras) +1
        ELSE DATEPART(hour,Datum)
END
ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS

Děkuji chlapci!
Tohle se už blíží k tomu co potřebuji, jen to opravdu počítá co píše kolega Peter.
Hodnota po 15min je výkon, který jede vždy od začátku tj, 00-15,15-30,30-45,45-00 a aby byly hodnoty správně počítány, musí součet čtvrthodin odpovídat celé hodině po.
Ještě tedy upřesním...
1.1.2020 00:15 + 00:15 + 00:30 + 00:30 + 00:45 + 01:00
Pak bude 1.1.2020 01:00 xxx kWh
(00:15 + 00:15 + 00:30 + 00:30 + 00:45 + 01:00)

Peteruv kód je pro mě dost složitý :-/
...

 
Nahoru Odpovědět
25. února 16:36
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:26. února 6:14

Ještě jsem si všimnul, že podle tohoto kódu přibyla nula, díky posunutí +1..Výsledek jsou dvě hodiny ve formátu 24 a 0 což také není žádoucí.

 
Nahoru Odpovědět
26. února 6:14
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 6:31

Tak malý zásah do úpravy kódu a vyřešeno :-)
Velice Vám pánové děkuji!!

SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minuteas)  in (15,30,45)  THEN DATEPART(houras) +1

        ELSE DATEPART(houras)
END as Hodina
, sum(kW) as kW


from [dbo].[Test_6]

group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minuteas)  in (15,30,45)  THEN DATEPART(houras) +1
        ELSE DATEPART(houras)
END

ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS



go
 
Nahoru Odpovědět
26. února 6:31
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 6:36

Konečný kód..

SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minuteas)  in (15,30,45)  THEN DATEPART(houras) +1

        ELSE DATEPART(houras)
END as Hodina
, sum(kW)/4 as kWh


from [dbo].[Test_6]

group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minuteas)  in (15,30,45)  THEN DATEPART(houras) +1
        ELSE DATEPART(houras)
END

ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS



GO
 
Nahoru Odpovědět
26. února 6:36
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 8:09

Tak zpět....
Po důkladné kontrole mi začátek vychází úžasně, ale po přechodu na jiný den se mi to už rozchází...

 
Nahoru Odpovědět
26. února 8:09
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 10:11
SELECT
Datum,
DATEPART(minute, datum) as Minuta,
DateAdd(mi, -(DatePart(mi, Datum))+15, Datum) as Datum_2,
kW
from

[dbo].[Pomocná_Tab_Datum_3]






GO

Jsem bezradný...

 
Nahoru Odpovědět
26. února 10:11
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 12:17

Myslel jsem, že to zgrupnu po hodině, jenže po kontrole to nesedí

SELECT
Datum,
--CAST(Datum as date) as Datum,
DATEPART(minute, datum) as Minuta,
DateAdd(mi, -(DatePart(mi, datum)) +15, datum) as Datum_2
,sum(kW) as kW,
DATEPART(hour,datum) +1 as Hodina

from

[dbo].[Pomocná_Tab_Datum_3]

group by
Datum,
DATEPART(hour,datum)
--DateAdd(mi, -(DatePart(mi, datum))+15, datum)



ORDER BY
3 ASC, 4 ASC OFFSET 0 ROWS




GO
 
Nahoru Odpovědět
26. února 12:17
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 12:18

..

 
Nahoru Odpovědět
26. února 12:18
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 14:39

Proč jednoduše nevypisuješ záznamy, ve kterých čas odpovídá celé hodině, jako by to byly záznamy s časovým posunem -45 minut?

Nahoru Odpovědět
26. února 14:39
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
c.bohumil
Člen
Avatar
Odpovídá na DarkCoder
c.bohumil:26. února 14:50

Časový posun o 45min chápu. Jak to ale, provést aby se suma, čtyř 15min po sobě jdoucí, spárovala s datumem následujícím netuším.

 
Nahoru Odpovědět
26. února 14:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 14:57

A proč by si je chtěl párovat? Každá hodnota je stavová a nesouvisí s žádnou jinou hodnotou. Proto vždy vypíšeš hodnotu v posledním časovém intervalu, pouze s upraveným časovým razítkem.

Nahoru Odpovědět
26. února 14:57
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
c.bohumil
Člen
Avatar
c.bohumil:26. února 15:05
07.05.2020 15:15        0
07.05.2020 15:30        0
07.05.2020 15:45        0
07.05.2020 16:00        451
07.05.2020 16:15        474
07.05.2020 16:30        392
07.05.2020 16:45        474
07.05.2020 17:00        431
07.05.2020 17:15        385

Příklad..
Potřebuji hodnotu ze dne 07.05.2020 a hodiny 17:00
Výsledek musí být 1771

Editováno 26. února 15:06
 
Nahoru Odpovědět
26. února 15:05
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 15:29

Pokud jsou to jednotlivé hodnoty stanovené vždy za 15 minut a nikoli stavové, situace je pak jiná. Způsobů je několik.

Vezmeš záznam, analyzuješ datum a čas, z toho určíš nový řetězec. Zjistíš, zda-li se v nové tabulce nenachází. Pokud ne, zapíšeš nový řetězec do tabulky spolu s hodnotou na daném záznamu. Pokud ano, přičteš hodnotu k danému záznamu druhé tabulky. Toto provedeš nad každým záznamem. Výsledkem jsou data v druhé tabulce.

Další způsob je že si zjistíš počet záznamů v tabulce. Na základě procházení konkrétního záznamu dokážeš určit, zda existuje grupa čtyř po sobě jdoucích dat patřících k sobě. Zapisovat budeš pouze záznamy s časovou hodnotou 15 minut a budeš aktualizovat hodnotu v druhé tabulce přičtením hodnot následujících tří záznamů (popř. zbylých). Ještě si musíš ošetřit prvních N záznamů, pokud nezačínají časovou hodnotou 15 minut.

Nahoru Odpovědět
26. února 15:29
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
c.bohumil
Člen
Avatar
Odpovídá na DarkCoder
c.bohumil:26. února 15:50

Data jsou reálná a každým dnem přibývají. Teď řeším rok 2020,následně rok 2021. Časově razítko je tedy vždy celá hodina po 15min. Nevýhoda všeho je, že musí být součet čtyř 15min uvedený v následujícím datu a času.

 
Nahoru Odpovědět
26. února 15:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 16:07

Nevýhoda všeho je, že musí být součet čtyř 15min uvedený v následujícím datu a času.

To už jsou drobnosti.. Pošli prvních 10 a posledních 10 záznamů databáze, ať vidím její hranice a tím i adekvátní podobu předchozího a následujícího roku. To má vliv na prefixovou a postfixovou část algoritmu..

Rozumím tomu správně že:

07.05.2020 16:15        474
07.05.2020 16:30        392
07.05.2020 16:45        474
07.05.2020 17:00        431

Musí být uloženo jako: (je časové razítko správně?)

07.05.2020 17:15        1771
Nahoru Odpovědět
26. února 16:07
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
c.bohumil
Člen
Avatar
Odpovídá na DarkCoder
c.bohumil:26. února 16:22

Takto by to mělo být

O7.05.2020 17:00        1771

Budu později u PC, tak pošlu.
Jsou to časové úseky měření po 15min kW, takže nikdy není konec.

Editováno 26. února 16:24
 
Nahoru Odpovědět
26. února 16:22
Avatar
c.bohumil
Člen
Avatar
Odpovídá na DarkCoder
c.bohumil:26. února 18:30

Můžu si data rozdělit roky pokud by to pomohlo, ale kratší časový úsek není žádoucí.

 
Nahoru Odpovědět
26. února 18:30
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 19:41

To je docela podstatná věc to rozdělení, ať už z logického hlediska tak programátorského.

Pokud bychom měli následující úryvek databáze:

2022-01-01 00:00        0
2022-01-01 00:15        0
2022-01-01 00:30        0
...

pak z logického hlediska patří první řádek k předchozímu roku společně se třemi dalšími předchozími záznamy a neměl by tudíž mít visačku roku 2022.

Z programátorského hlediska je řešení celého problému podstatně jednoduší.

Takže rozhodně použij tuto formu:

2022-01-01 00:15        1
2022-01-01 00:30        2
2022-01-01 00:45        3
2022-01-01 00:00        4
...
2022-12-31 23:15        10
2022-12-31 23:30        20
2022-12-31 23:45        30
2022-12-31 00:00        40

Z toho chceme dostat toto:

2022-01-01 00:00        10
...
2022-12-31 00:00        100

Záznamy jsou chronologicky řazeny za sebou. Pokud existuje čtvrtý záznam, pak existující tři předchozí. Takže když vypisuješ nový záznam (každý čtvrtý), dokážeš určit hodnotu záznamu tvořící skupinu čtyř velice snadno.

Nahoru Odpovědět
26. února 19:41
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
DarkCoder
Člen
Avatar
Odpovídá na c.bohumil
DarkCoder:26. února 21:50

Jak jednoduše a efektivně to celé můžeš zpracovat ukazují následující dva způsoby:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

#define STRLEN 16
#define GROUPINDEX 4

struct sRecord {
        char date[STRLEN + 1];
        unsigned kW;
};

struct sRecord data[] = {
        {"2022-01-01 00:15", 1},
        {"2022-01-01 00:30", 3},
        {"2022-01-01 00:45", 5},
        {"2022-01-01 00:00", 7},
        {"2022-12-31 23:15", 40},
        {"2022-12-31 23:30", 30},
        {"2022-12-31 23:45", 20},
        {"2022-12-31 00:00", 10},
        {"", 0}
};

int main(void) {

        int recpos = 0;

        while (strcmp(data[recpos].date, "")) {
                if (!((recpos + 1) % GROUPINDEX)) {
                        for (int i = 1; i < GROUPINDEX; i++) data[recpos].kW += data[recpos - i].kW;
                        printf("%s\t%u\n", data[recpos].date, data[recpos].kW);
                }
                recpos++;
        }

        return 0;
}

Tento způsob vyžaduje ukončovací patici databáze v podobě prázdného řetězce. Postupně prochází záznamy jeden po druhém a ověřuje je na jejich platnost (provádí test na prázdný řetězec). Pro každý čtvrtý záznam stanoví novou hodnotu kW na základě hodnoty daného záznamu a tří předchozích a vypíše záznam. Tato verze není nejrychlejší (porovnání řetězců, procházení každého záznamu), jejím smyslem je ukázat jeden možný způsob.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

#define STRLEN 16
#define GROUPINDEX 4

struct sRecord {
        char date[STRLEN + 1];
        unsigned kW;
};

struct sRecord data[] = {
        {"2022-01-01 00:15", 1},
        {"2022-01-01 00:30", 3},
        {"2022-01-01 00:45", 5},
        {"2022-01-01 00:00", 7},
        {"2022-12-31 23:15", 40},
        {"2022-12-31 23:30", 30},
        {"2022-12-31 23:45", 20},
        {"2022-12-31 00:00", 10}
};

int main(void) {

        int reccount = sizeof data / sizeof(struct sRecord);

        for (int i = GROUPINDEX - 1; i < reccount; i += GROUPINDEX) {
                for (int j = 1; j < GROUPINDEX; j++) data[i].kW += data[i - j].kW;
                printf("%s\t%u\n", data[i].date, data[i].kW);
        }

        return 0;
}

Tento způsob na rozdíl od předchozího způsobu nevyžaduje ukončovací patici databáze, pouze samotné záznamy. Zjistí se počet záznamů v databázi. Postupně prochází každý čtvrtý záznam, pro který stanoví novou hodnotu kW na základě hodnoty daného záznamu a tří předchozích a vypíše záznam. Tato verze je nejrychlejší možná. Z této verze se můžeš inspirovat způsobem zápisu SQL dotazu, popř. se na dotazy úplně vykašlat.. :-)

V obou verzích dojde k následovnému výpisu:

2022-01-01 00:00        16
2022-12-31 00:00        100

Jako vstupní data byly použity záznamy v následujícím formátu:

2022-01-01 00:15        1
2022-01-01 00:30        3
2022-01-01 00:45        5
2022-01-01 00:00        7
2022-12-31 23:15        40
2022-12-31 23:30        30
2022-12-31 23:45        20
2022-12-31 00:00        10

Kód psán v C, pokud něco není jasné, ptej se.

Nahoru Odpovědět
26. února 21:50
"Chceš-li předávat své znalosti, měj kvalitní podklady."
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:27. února 10:26

Tak asi tak

SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minute,Datum) in (15,30,45) THEN DATEPART(hour,Datum) + 1
        ELSE DATEPART(hour,Datum)
END as Hodina
, sum(t.kw) as kw
from (SELECT DATEADD(minute,45,Datum) as Datum,kw DROM  [dbo].[Test5]) t
group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minute,Datum) in (15,30,45) THEN DATEPART(hour,Datum) + 1
        ELSE DATEPART(hour,Datum)
END
ORDER BY 1,2
 
Nahoru Odpovědět
27. února 10:26
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
c.bohumil
Člen
Avatar
c.bohumil:27. února 19:42

Jsem rád, že trochu dám MSQL, C jazyk mi neříká vůbec nic. Myšlenku, ale chápu .Děkuji

 
Nahoru Odpovědět
27. února 19:42
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:27. února 19:49

Tvůj kód funguje až na 0 a 24h.Stačilo by už hodinu 0 a 24 sečíst a přiřadit časové razítko k hodině 24.
Dokážu si představit další dotaz na tuto tabulku. S tím datumem, ale stále zápasím...:-/

 
Nahoru Odpovědět
27. února 19:49
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:27. února 23:07

pisu to jenom po pameti ale asi by podle toho stacili upravit CASE

CASE
        WHEN DATEPART(minute,Datum) in (15,30,45) THEN DATEPART(hour,Datum) + 1
        WHEN DATEPART(hour,Datum) = 0 THEN 24
        ELSE DATEPART(hour,Datum)
END

Tak snad OK

 
Nahoru Odpovědět
27. února 23:07
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:28. února 5:19

Takto to sjednotí hodinu 0 a 24, což je super, ale součet je neznámí.

SELECT
CAST(Datum as date) as Datum,
CASE
        WHEN DATEPART(minute,Datum)  in (15,30,45)  THEN DATEPART(hour,Datum) +1
                WHEN DATEPART(hour,Datum) = 0 THEN 24
        ELSE DATEPART(hour,Datum)
END as Hodina
, sum(kW) as kWh


from [dbo].[Pomocná_Tab_Datum_3]

group by
CAST(Datum as date),
CASE
        WHEN DATEPART(minute,Datum)  in (15,30,45)  THEN DATEPART(hour,Datum) +1
                WHEN DATEPART(hour,Datum) = 0 THEN 24
        ELSE DATEPART(hour,Datum)
END

ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS



GO
 
Nahoru Odpovědět
28. února 5:19
Avatar
Petan
Člen
Avatar
Petan:28. února 6:39

myslim ze tam patri ve from to co jsem psal predtim

from (SELECT DATEADD(minute,45,Datum) as Datum,kw DROM  [dbo].[Test5]) t

pokud ne posli vzorek dat a pozadovany vysledek (ne jako obrazek ) a ja to testnu

 
Nahoru Odpovědět
28. února 6:39
Avatar
c.bohumil
Člen
Avatar
c.bohumil:28. února 7:56
from (SELECT DATEADD(minute,45,Datum) as Datum,kw DROM

Tento řádek se mi tam nepodařilo zakomponovat, stále se tomu něco nelíbí. Přikládám .bak soubor s daty. Nebo mám přiložit v jiné podobě?
Děkuji

 
Nahoru Odpovědět
28. února 7:56
Avatar
c.bohumil
Člen
Avatar
c.bohumil:28. února 7:59

Bak.Soubor

 
Nahoru Odpovědět
28. února 7:59
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. února 8:14

Ale, proc to neudelate, jak jsem psal na zacatku? vytvorit si pomocny sloupec a grupovat to az dalsim selectem? Nebo to v mssql nejde? Nebo to tam pridat leftjoinem, jestli by to slo.

SELECT
    a.id,
    SUM(a.value),
    b.datum
FROM
    tabulka a
        LEFT JOIN (
              SELECT
                   a.id,
                   CASE
                         WHEN DATEPART(minute,a.Datum) in (15,30,45) THEN DATEPART(hour,a.Datum) + 1
                         ELSE DATEPART(hour,a.Datum)
                  END datum
                 ) b
GROUP BY b.datum

---


SELECT
    b.id,
    SUM(b.value),
    b.datum
FROM (
              SELECT
                   a.id,
                   CASE
                         WHEN DATEPART(minute,a.Datum) in (15,30,45) THEN DATEPART(hour,a.Datum) + 1
                         ELSE DATEPART(hour,a.Datum)
                  END AS datum
                  a.value
            FROM
                  tabulka a
             ) b
GROUP BY b.datum

Kdyz ten case pouzivate 2x, tak to preci musi byt pomale.
Na druhou stranu, grupovat to podle datumu tez neni uplne cool, pokud nad sloupcem nemate index a pokud datum v prubehu zmenite, cimz v podstate prijde o ten index.
Lepsi by bylo vytvorit si prave tu pomocnou tabulku s upravenym datumem, indexy.

 
Nahoru Odpovědět
28. února 8:14
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. února 9:13

A jeste bych tam mozna pridal pri testovani kontrolu na pocet hodnot. COUNT(b.value), abys videl, ze pouzil 4 hodnoty.

Jinak, nespolehal bych na ten cas, ze bude vzdy 15 min. Treba se to trefi na 14.99. Takze bych tu podminku spis upravil na if-else.
A proc je tam pouzito WHEN DATEPART(minute,a.Datum) in (15,30,45), kdyz by efektivnejsi bylo dat prvni podminku co nejkratsi?

WHEN DATEPART(minute,Datum) in (15,30,45) ... else ...
WHEN DATEPART(minute,Datum) in (0) ELSE ...
WHEN DATEPART(minute,Datum) < 15 ...

Ups, v tom sql dotazu je asi fura chyb. Uz ted vidim jednu. Tam se jedna jen o tu cast datumu. Tak to zkusim znova :)

SELECT
    b.id,
    SUM(b.value),
    b.datum2,
    COUNT(b.value)
FROM (
              SELECT
                   a.id,
                   a.value,
                   CASE
                         WHEN DatePart(minute, a.datum)>=15
                             THEN DateAdd(minute, - DatePart(minute, a.datum) + 15, a.datum)
                             ELSE DateAdd(minute, - DatePart(minute, a.datum) + 15 - 60, a.datum)
                   END AS datum2
            FROM
                  tabulka a
             ) b
GROUP BY b.datum2
Editováno 28. února 9:15
 
Nahoru Odpovědět
28. února 9:13
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:28. února 9:35
SELECT
CAST(Datum as date) as Datum,
DATEPART(hour,Datum) + 1 as Hodina,
sum(kW) as kWh
--,count(*),MIN(Datum),MAX(Datum)
from (SELECT DATEADD(minute,45,Datum) as Datum,kw FROM [dbo].[Test_kW]) X
group by
CAST(Datum as date),
DATEPART(hour,Datum)
ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS

snad OK

 
Nahoru Odpovědět
28. února 9:35
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:28. února 10:15

Když odeberu +1 , tak je vše OK.
Malá úprava a mám z toho kWh.
Děkuji za výbornou práci a pomoc!

SELECT
CAST(Datum as date) as Datum,
DATEPART(hour,Datum) as Hodina,
sum(kW)/4 as kWh
--,count(*),MIN(Datum),MAX(Datum)
from (SELECT DATEADD(minute,45,Datum) as Datum,kw FROM [dbo].[Pomocná_Tab_Datum_3]) X
group by
CAST(Datum as date),
DATEPART(hour,Datum)
ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS
 
Nahoru Odpovědět
28. února 10:15
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Peter Mlich
c.bohumil:28. února 10:18

Tvůj kód jsem samozřejmě také zkoušel, ale stále mi to házelo chyby s kterými jsem se nedokázal poprat.
Děkuji za vynaložení energie na můj problém! :-)

 
Nahoru Odpovědět
28. února 10:18
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. února 11:45

Chyby si musis hold odladit. S ms nedelam.
Ale, to Petanovo druhe reseni je takove elegantni. Pricte 45 min. Tim padem se mu srovnaji spravne hodiny. A pak to grupuje podle dnu a hodin. Zgrupovani je hotovo a jen treba pridat jeste spravne datum do vysledku. Coz by resil ten CASE, kdybys ho tam mel.

2022-12-31 23:15        40
2022-12-31 23:30        30
2022-12-31 23:45        20
2022-12-31 00:00        10

Celou tuto serii ti posune na d+1, 2022-12-31+1, a protoze datum je tak nevhodne zvolene, tak i m+1 a r+1 :)

SELECT
       CAST(Datum1 as date) as Datum,
       DATEPART(hour, Datum1) as Hodina,
       sum(kW)/4 as kWh
FROM (
          SELECT
                   CASE
                         WHEN DatePart(minute, Datum)>=15
                             THEN DateAdd(minute, - DatePart(minute, Datum), Datum)
                             ELSE DateAdd(minute, - DatePart(minute, Datum) - 60, Datum)
                   END AS Datum1
                   kw
           FROM
                  [dbo].[Pomocná_Tab_Datum_3]
           ) X
group by
            CAST(Datum1 as date),
            DATEPART(hour, Datum1)
 
Nahoru Odpovědět
28. února 11:45
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. února 11:50

ach jo, za END AS Datum1 ma byt carka END AS Datum1, protoze je tam seznam sloupcu
No, a slo by to teda i odcitanim

SELECT
       CAST(DateAdd(hour, -1, Datum2) as date) as Datum,
       DATEPART(hour, DateAdd(hour, -1, Datum2)) as Hodina,
       sum(kW)/4 as kWh
FROM (
          SELECT
                   DATEADD(minute,45,Datum) as Datum2,
                   kw
           FROM
                  [dbo].[Pomocná_Tab_Datum_3]
           ) X
group by
            CAST(Datum2 as date),
            DATEPART(hour, Datum2)

Ty mas cely datum o hodinu posunuty. Takze musis pro vysledek posunout datum zpet. A pak teprve z men vytahovat DATE a part-HOUR.

Editováno 28. února 11:51
 
Nahoru Odpovědět
28. února 11:50
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Peter Mlich
c.bohumil:28. února 12:38

Ajooo,máš pravdu...:-( už mě jebne z těch čísel a datumů ....:-D

 
Nahoru Odpovědět
28. února 12:38
Avatar
c.bohumil
Člen
Avatar
c.bohumil:28. února 13:12

Takhle mi to teď vychází ať přidávám, nebo ubírám...

Editováno 28. února 13:15
 
Nahoru Odpovědět
28. února 13:12
Avatar
c.bohumil
Člen
Avatar
c.bohumil:28. února 13:15

...

 
Nahoru Odpovědět
28. února 13:15
Avatar
Petan
Člen
Avatar
Petan:1. března 7:20

Jsem zmaten. Jak vlastne chces provest tu grupaci, posli nejaky obrazek aby vypadal jak tem muj

 
Nahoru Odpovědět
1. března 7:20
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:1. března 7:41

c.bohumil - Dobre. To mas fuk, ktery pouzijes. Mas tu nekolik ruznych zpusobu, ze kterych to snad poskladas, kdyz vis, jak to chces :)

 
Nahoru Odpovědět
1. března 7:41
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:1. března 9:03

Máš to přesně, správně znázorněno jak by to mělo být. Když si testneš data která jsem dal pro test, tak se tam v jednom případě posunou hodnoty o hodinu se správným datumem. V druhém případě hodnot správně, ale datum posunutý.

 
Nahoru Odpovědět
1. března 9:03
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:1. března 9:45

TO JAKO VAZNE PO 26.8.2020 23HOD MA NASLEDOVAT 26.8.2020 0HOD A POTOM 27.8.2020 1HOD ?

 
Nahoru Odpovědět
1. března 9:45
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:1. března 10:20

Jsou to časové úseky. 0-15,15-30,30-45,45-00.

15= zaměřena hodnota,
30=zaměřena hodnota,
45=zaměřena hodnota,
00=zaměřena hodnota(tahle hodnota hodiny jde k datumu kde začíná 15min
Hodnota je měřená každých 15min a k 15, 30,45,00 je naměřená hodnota. To znamená, musí datum odpovídat vždy kdy začalo 15min.
A 23:15=00:00 je stejný datum.

No, asi trochu víc zmatený.. 😕

 
Nahoru Odpovědět
1. března 10:20
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Petan
c.bohumil:1. března 10:54

0h bráno jako 24h. Jestli bude 0,nebo 24h by byla jedno.

 
Nahoru Odpovědět
1. března 10:54
Avatar
Petan
Člen
Avatar
Odpovídá na c.bohumil
Petan:1. března 18:15

No teda jestli to chapu/nechapu pak by melo stacit toto

from (SELECT DATEADD(minute,45,Datum) as Datum,kw FROM [dbo].[Pomocná_Tab_Datum_3]) X

nahradit timto

from (SELECT DATEADD(minute,-15,Datum) as Datum,kw FROM [dbo].[Pomocná_Tab_Datum_3]) X
 
Nahoru Odpovědět
1. března 18:15
Avatar
c.bohumil
Člen
Avatar
c.bohumil:5. dubna 5:02

Ahoj kluci.
Mám tu další oříšek, teda aspoň pro mě..
Dotaz nakonec díky vám používám tento

SELECT
CAST(Datum as date) as Datum,
DATEPART(hour,Datum) as Hodina,
CAST(sum(kW)/4.0/1000 AS decimal(9,5) ) as mWh
from (SELECT DATEADD(minute,45,Datum) as Datum,kw FROM [dbo].[Pomocná_Tab_Datum_3]) X
group by
CAST(Datum as date),
DATEPART(hour,Datum)
ORDER BY
1 ASC, 2 ASC OFFSET 0 ROWS
GO

Přesný výsledek vychází na 5 desetinných míst a pro vyhodnocení potřebuji jen 3 desetinná místa.
Ale....nemůžu zaokrouhlovat pro součet celého měsíce, protože by se mi to rozcházelo, respektive nesouhlasilo s daty které dostávám od ČEZu pro vyhodnocení. Oni ubírají poslední 2 desetinná místa a přičítají je do další hodiny. Mají napsaný script.
Nějaký tip jak to v MSSql udělat?
Děkuji

Editováno 5. dubna 5:03
 
Nahoru Odpovědět
5. dubna 5:02
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:5. dubna 9:54

Obavam se, ze tohle jednoduse udelat nepujde. Asi to bude treba obalit dalsim selectem.
Pocitejme s tim, ze tabulka vychazi dobre, i soucty. Takze, ta je ok, jen se nejaka cisla musi trochu upravit.
A take muze nastat, ze dany radek, kam chces pricist/odecist, nemusi existovat.

  • zkopiruj a, b, c, value
  • odecti (odrizni) od value posledni 2 deset. mista value=floor(va­lue*1000)/1000
  • pricti k value mista z predchozi hodiny value = value + X, (select value from ... where hodina-1) = Y, X = y*1000 - floor(Y*1000)

https://docs.microsoft.com/…transact-sql?…

SELECT
    FLOOR(123.45), -- 123
    FLOOR(-123.45), -- -124 -- podle mne, toto je chyba, spravne by to melo dat -123, ne? ale to nebudes stejne potrebovat
    FLOOR($123.45); -- 123.0000 --- ten dolar nevim, co je

floor odrezava desetinou carku
A = 34.53485
B = 53.67832
C = floor(A*1000)/1000 = floor(34534.85)/1000 = 34534/1000 = 34.534
D = (B*1000 - floor(B*1000))/1000
    = (53678.32 - floor(53678.32))/1000
    = (53678.32 - 53678)/1000 = 0.32/1000
    = 0.00032
E = C + D = 34.534 + 0.00032

Ale, ted premyslim, ze to mozna ma byt jinak.

  • potrebujes odecist z aktualni hodiny vse za mistem 4
  • toto pricist na nasledujici hodinu (kde uz nejaka mista mas)
  • a v dalsim kroku pro tu upravenou dalsi hodinu udelat totez
  • s tim, ze u te prvni to budes mit chybne, pokud neznas, kolik tam pricitaji a tim padem i vsechny ostatni :)
B = 53.67832 -- aktualni
C = 98.12345 -- nasledujici
D = (B*1000 - floor(B*1000))/1000
    = (53678.32 - floor(53678.32))/1000
    = (53678.32 - 53678)/1000
    = 0.32/1000
    = 0.00032
new B = B - D
new C = C + D
---
B = 98.12345 + 0.00032 -- aktualni (new C)
C = 22.75544 -- nasledujici
D = (B*1000 - floor(B*1000))/1000 = ... 0.00077
new B = B - D
new C = C + D
Editováno 5. dubna 9:55
 
Nahoru Odpovědět
5. dubna 9:54
Avatar
c.bohumil
Člen
Avatar
Odpovídá na Peter Mlich
c.bohumil:6. dubna 16:02

Potřebuji vzít poslední dvě čísla, tak aby zbylo číslo s tisícinou. Tato dvě odebraná čísla přičíst k následující hodině a v této hodině totéž, atd.. Teoreticky součet stále zůstane a vezme ty dvě poslední čísla už sečtená z předešlého součtu..
Tvl, to je zase úkol... 😁

 
Nahoru Odpovědět
6. dubna 16:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 54 zpráv z 54.