[SQL - MS SQL2000] combinatie DATEADD en BETWEEN instructie?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
Op basis van een ellenlange (miljoenen records) tabel moet ik maandelijks een aantal records selecteren, en deze vervolgens in een CSV bestand steken met een aantal kolommen. De output hiervan ziet er zo uit:
LogDate, AM25L\3Sec\ddd_10av, AM25L\3Sec\ff_10av, AM25L\3Sec\ff_10x
1/06/2013, 322, 9.5, 13.8
1/06/2013 00:10:00, 318, 9.9, 14.4
1/06/2013 00:20:00, 316, 9.7, 15.2
1/06/2013 00:30:00, 318, 9.9, 15.7
1/06/2013 00:40:00, 313, 9.7, 15
1/06/2013 00:50:00, 313, 9.3, 13.8
1/06/2013 01:00:00, 318, 8.2, 13
1/06/2013 01:10:00, 318, 8, 13
...
Tot nog toe worden deze CSV bestanden gemaakt via een tool meegeleverd door de fabrikant v/d hardware die wij hier gebruiken. Helaas moet men wel manueel deze bestanden maken en hier gaan heel veel werkuren aan verloren, dus ik mag de zaak automatiseren.

De structuur van de basistabel is zo dat er gewoon geen structuur, sortering of normalisering aanwezig is.
De meetgegevens worden gewoon op een hoop gegooid (a rato van 800000/dag) en daarmee is de kous af.

Met deze code kom ik al aardig in de buurt van de output die ik hier reeds heb geplakt, op één detail na:
in de output zie je de timestamps steeds met 10 minuten verhogen. Met mijn query krijg je gewoon voor elke timestamp een resultaat en dat zijn er echt veel te veel. Dus nu ben ik op zoek naar een manier om in deze query een voorwaarde te plaatsen die aangeeft dat er slechts per 10 minuten een resultaat moet weergegeven worden.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT     t1.LogDate,
           t1.LogValue AS 'AM25L\3sec\ddd_10av', 
           t2.LogValue AS 'AM25L\3sec\ff_10av', 
           t3.LogValue AS 'AM25L\3sec\ff_10x'
FROM         [Log] t1 
             INNER JOIN [Log] t2 ON t1.LogDate = t2.LogDate 
             INNER JOIN [Log] t3 ON t1.LogDate = t3.LogDate
WHERE     (t1.LogDate BETWEEN 'Jun 1 2013 00:00AM' AND 'Jun 30 2013 00:00AM') 
                      AND (t1.StationName = 'AM25L')  
                      AND (t2.StationName = 'AM25L')
                      AND (t3.StationName = 'AM25L')
                      AND (t1.GroupName = '3sec')
                      AND (t2.GroupName = '3sec')
                      AND (t3.GroupName = '3sec')
                      AND (t1.VariableName = 'ddd_10av')
                      AND (t2.VariableName = 'ff_10av')
                      AND (t3.VariableName = 'ff_10x')
ORDER BY t1.LogDate

Wat mijn code precies doet: de 3 variabelen die ik op het einde aanmerk selecteren en deze in een kolomvorm gooien via de JOIN instructie. Omdat er meerdere combinaties mogelijk zijn van StationName, GroupName en VariableName in de brontabel heb ik dus redelijk wat AND operators moeten plaatsen.

Nu wil ik dus nog een instructie plaatsen die er voor zorgt dat er alleen op (vorig)tijdstip + 10 minuten geselecteerd wordt binnen het interval van een maand. Hiervoor denk ik op dit moment aan volgende mogelijkheden:
- zoals ik met andere soortgelijke queries reeds gedaan heb: automatisch een tijdelijke tabel aanmaken met de gewenste timestamps in en deze joinen met de output van mijn query hierboven. Deze optie zou ik het liefst willen vermijden, het lijkt mij meer een bric-a-brac oplossing die mijn SQL onkunde aantoont.
- een andere transact sql oplossing: een eenvoudige loop programmeren die telkens een nieuwe query aanmaakt en uitvoert, maar dat kost volgens mij veel CPU van de server.
- werken met de DATEADD functie die mij hiervoor aangewezen lijkt. Alleen heb ik geen flauw idee waar ik deze juist zou moeten plaatsen. In de WHERE clausule levert hij maar één enkele record op (startdatum + 10 minuten logischerwijs). Ik heb ook reeds geprobeerd om de BETWEEN te combineren met deze functie, maar dat levert alleen maar veel error boodschappen op of slechts een enkelvoudige record als output: WHERE t1.LogDate BETWEEN(eerstedatum,DATEADD(mi,10,einddatum))

Nu is mijn vraag dus:
- kan ik überhaupt de DATEADD functie gebruiken om de timestamps per 10 minuten te verhogen ipv ze allemaal af te gaan? Zoja, waar moet ik die dan plaatsen?
- of ben ik gewoon in de verkeerde richting aan het zoeken?

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 18-08 21:31
Een GROUP BY op een afgeronde/afgekapte LogDate (en voor de rest van de waardes kiezen of je min/max/avg/sum/iets anders wilt).

Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
Naar aanleiding van jouw suggestie heb ik dit artikel gevonden ivm GROUP BY:
http://stackoverflow.com/...-by-hour-or-by-10-minutes

Nu vraag ik me wel af of ik hiermee de eigenlijke LogValue niet ga manipuleren/afronden/...? Dat is niet de bedoeling, ik wil enkel de waardes selecteren die geregistreerd werden precies op vorigtijdstip + 10 minuten. Alles wat tussenin valt mag weg, maar de waardes zelf mag ik niet afronden...

Misschien begrijp ik de functionaliteit van GROUP BY verkeerd, in dat geval mijn excuses :)
Ik zal allesinds nog even doorlezen en leren wat ik hier mee kan.

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • WormLord
  • Registratie: September 2003
  • Laatst online: 01-08 12:04

WormLord

Devver

Is het niet mogelijk om alleen de resultaten te selecteren die precies op de 10-minuten tijden vallen? Dus op xx:00:00, xx:10:00, xx:20:00, xx:30:00, etc. Dan kun je wel iets met DATEPART doen.

Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
Dat is dus net wat ik tracht uit te zoeken ;)

Mijn query werkt goed, maar geeft alleen teveel data terug. Ik wil alleen de records die vallen op +10min, zoals in de gepaste output. Wat er tussenin valt moet weg, zonder verdere manipulatie van de gevonden resultaten.

*edit* zoals ik reeds zei kan ik perfect in transact sql een scriptje schrijven om automatisch een
tabel te maken met de gewenste timestamps in en deze dan vervolgens weer te joinen. Alleen vraag ik mij af of dat echt wel een goede oplossing is?

Ik zou graag het niveau van mijn sql code opkrikken en dus wil ik eerst eens kijken of ik deze code
nog kan aanpassen ipv weer ellenlange scripts te schrijven, zoals ik vroeger vaak deed.

[ Voor 45% gewijzigd door Kapoen op 09-07-2013 17:53 ]

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Nu online
Waarom hang je niet gewoon de Sql Server Profiler aan de database om te kijken wat voor query die tool draait?

Oh ja: MSSQL2000?? Het is 2013.. :X

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
sig69 schreef op dinsdag 09 juli 2013 @ 20:07:
Oh ja: MSSQL2000?? Het is 2013.. :X
Het geheel (hardware en software) is aangekocht als een grote blackbox en verder heb ik daar ook geen inspraak in jammer genoeg. De tool van de fabrikant is ook gesloten en werkt op basis van hun eigen bestandsformaat.

Mijn bedenkingen over deze situatie heb ik reeds lang geleden overgemaakt, maar ondertussen blijf ik professioneel en roei ik met de riemen die ik heb :)

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Nu online
Ik vermoedde al zoiets :). Maar dat die tool gesloten is maakt niet uit, je hangt de profiler toch aan je database?

[ Voor 16% gewijzigd door sig69 op 09-07-2013 21:51 ]

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
Ik ben vergeten te zeggen dat zij een soort van 'dump' maken in een gesloten bestandsformaat en dat de tool daarvan z'n gegegevens haalt. Erg efficiënt kan het niet zijn als ik zie hoelang dat allemaal duurt...

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
sig69 schreef op dinsdag 09 juli 2013 @ 20:07:
Waarom hang je niet gewoon de Sql Server Profiler aan de database om te kijken wat voor query die tool draait?

Oh ja: MSSQL2000?? Het is 2013.. :X
Misschien stamt de software uit 2000?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • TallManNL
  • Registratie: Oktober 2005
  • Laatst online: 08-09 11:05
WormLord schreef op dinsdag 09 juli 2013 @ 17:37:
Is het niet mogelijk om alleen de resultaten te selecteren die precies op de 10-minuten tijden vallen? Dus op xx:00:00, xx:10:00, xx:20:00, xx:30:00, etc. Dan kun je wel iets met DATEPART doen.
Als ik het me goed herinner ondersteunt SQL2000 nog geen Common Table Expressions en zal dit waarschijnlijk de makkelijkste optie zijn

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT     t1.LogDate,
           t1.LogValue AS 'AM25L\3sec\ddd_10av', 
           t2.LogValue AS 'AM25L\3sec\ff_10av', 
           t3.LogValue AS 'AM25L\3sec\ff_10x'
FROM         [Log] t1 
             INNER JOIN [Log] t2 ON t1.LogDate = t2.LogDate 
             INNER JOIN [Log] t3 ON t1.LogDate = t3.LogDate
WHERE     (t1.LogDate BETWEEN 'Jun 1 2013 00:00AM' AND 'Jun 30 2013 00:00AM') 
                      AND (t1.StationName = 'AM25L')  
                      AND (t2.StationName = 'AM25L')
                      AND (t3.StationName = 'AM25L')
                      AND (t1.GroupName = '3sec')
                      AND (t2.GroupName = '3sec')
                      AND (t3.GroupName = '3sec')
                      AND (t1.VariableName = 'ddd_10av')
                      AND (t2.VariableName = 'ff_10av')
                      AND (t3.VariableName = 'ff_10x')
                      AND (DATEPART(mi, t1.LogDate) in (0,10,20,30,40,50))
ORDER BY t1.LogDate


Mogelijk nog een Datepart erbij om je seconden te beperken dat je daadwerkelijk maar 1 meting per 10 minuten krijgen.

Die function wordt wel voor heel veel data doorgelopen dus kwa performance is dit niet helemaal licht.
Dan is een join met een temp table med de gewenste tijdstippen waarschijnlijk een stuk sneller.

[ Voor 10% gewijzigd door TallManNL op 10-07-2013 08:23 ]

geheelonthouder met geheugenverlies


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Nu online
Kapoen schreef op woensdag 10 juli 2013 @ 06:58:
Ik ben vergeten te zeggen dat zij een soort van 'dump' maken in een gesloten bestandsformaat en dat de tool daarvan z'n gegegevens haalt. Erg efficiënt kan het niet zijn als ik zie hoelang dat allemaal duurt...
Er is dan nog steeds een kleine kans dat je met Sql Server Profiler iets kan achterhalen. Ik ben alleen bang dat er niet simpel een query wordt afgevuurd. Op het moment dat er nog wat business logica uitgevoerd wordt is er een kans dat je met een query alleen niet de gewenste resultaten terug krijgt. Maar goed, dat is nu zaak om uit te zoeken dus.

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
TallManNL schreef op woensdag 10 juli 2013 @ 08:19:
[...]
Die function wordt wel voor heel veel data doorgelopen dus kwa performance is dit niet helemaal licht.
Dan is een join met een temp table med de gewenste tijdstippen waarschijnlijk een stuk sneller.
Na een rudimentaire test met een horloge kan ik bevestigen dat de join idd een stuk sneller is. Bedankt voor de extra code ivm de DATEPART functie, daar heb ik weer van bijgeleerd en dat kan ik zeker nog gebruiken voor andere scripts _/-\o_

Het ziet er dus naar uit dat ik mijn TSQL script voor het genereren van timestamps nog voorlopig niet kan pensioeneren. En een upgrade v/d backend van het systeem zit er voorlopig ook nog niet aan te komen jammer genoeg.

Bedankt aan iedereen voor de geboden hulp, ik ga er allesinds mee aan de slag voor het opzetten van een testomgeving van modernere databanken.

Clowns to the left of me, Jokers to the right


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Kapoen schreef op woensdag 10 juli 2013 @ 11:23:
[...]
Het ziet er dus naar uit dat ik mijn TSQL script voor het genereren van timestamps nog voorlopig niet kan pensioeneren. En een upgrade v/d backend van het systeem zit er voorlopig ook nog niet aan te komen jammer genoeg.
Hoezo moet je die timestamps genereren? Je use-case vraagt slechts om 6 regels in een tabel met alle 10-minuten tijden. De uren kan je negeren en de data's ook volgens je use-case.
Performance technisch zal het iets slechter presteren, maar dit zou ik even nameten als het een genereer dependency weghaalt (ik ben niet zo van scriptjes die zelf iets genereren voor niets)

Hooguit zou ik het hele zwikje in 1 SP zetten die dan een memory table genereert met die waardes zodat het wel 1 geheel blijft.

Acties:
  • 0 Henk 'm!

  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 10:53
Gomez12 schreef op woensdag 10 juli 2013 @ 21:58:
[...]

Hoezo moet je die timestamps genereren? Je use-case vraagt slechts om 6 regels in een tabel met alle 10-minuten tijden. De uren kan je negeren en de data's ook volgens je use-case.
Performance technisch zal het iets slechter presteren, maar dit zou ik even nameten als het een genereer dependency weghaalt (ik ben niet zo van scriptjes die zelf iets genereren voor niets)

Hooguit zou ik het hele zwikje in 1 SP zetten die dan een memory table genereert met die waardes zodat het wel 1 geheel blijft.
Om eerlijk te zijn had ik nog niet gedacht aan memory tables. Het concept ken ik wel, maar ik heb het gewoon overgeslagen omdat ik de performantie er van (vs echte tijdelijke tabellen die ik nadien drop) niet goed kan inschatten.

Ik heb voornamelijk schrik om de oude database server (qua hardware) te belasten. Het ding dient tegelijk als productie en archief server, en heeft nu al een stevige load qua cpu en geheugen gebruik. Mijn andere scripts moeten al miljoenen records verwerken, en het script van deze thread mag ik ondertussen ook al weer uitbreiden. Praktisch gezien ga ik meer timestamps moeten verwerken, in de honderdduizend per dag.

Tot nu toe gebruiken mijn andere scripts ook een aantal tijdelijke tabellen, die ik achteraf join en drop. Tot dusver lijkt me dat goed te werken zonder dat het de server extra zwaar belast. Ik ga de piste van de memory tables ook bekijken, eens kijken wat dat oplevert. Bedankt voor de tip _/-\o_

Clowns to the left of me, Jokers to the right

Pagina: 1