Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[SQL] Vraag m.b.t. query

Pagina: 1
Acties:

  • Tinuske
  • Registratie: September 2002
  • Laatst online: 26-08-2024
Ik heb een soort van logtabel met daarin het volgende

Datum | Waarde
01-01-2012 | 30
02-01-2012 | 30
03-01-2012 | 30
04-01-2012 | 30
05-01-2012 | 40
06-01-2012 | 40
07-01-2012 | 60
08-01-2012 | 60
09-01-2012 | 60

Nu wil ik een query die alleen de 1e rij + mutaties laat zien
Dus als resultaat :
01-01-2012 | 30
05-01-2012 | 40
07-01-2012 | 60

Heb vanalles al geprobeerd en gegoogled, maar kom niet tot de oplossing.
Kan bijv. wel een distinct gebruiken op de waardekolom, maar als ik er ook het datumveld erbij wil hebben werkt het al niet meer.

Wie helpt mij ?

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Welke queries heb je zoal zelf geprobeerd dan? Dan weten wij in welke richting er gedacht wordt en welke queries dus al uitgesloten kunnen worden.

  • Pathogen
  • Registratie: April 2004
  • Laatst online: 21-11 12:11

Pathogen

Shoop Da Whoop

SELECT datum, waarde
FROM tabel
WHERE (SELECT t2.waarde FROM tabel t2 WHERE t2.datum = tabel.datum -1) <> tabel.waarde

even de datumberekening doorvertalen naar je specifieke dbms

  • DukeBox
  • Registratie: April 2000
  • Laatst online: 18:38

DukeBox

loves wheat smoothies

select min(date) + waarde en group by waarde

Duct tape can't fix stupid, but it can muffle the sound.


  • Pathogen
  • Registratie: April 2004
  • Laatst online: 21-11 12:11

Pathogen

Shoop Da Whoop

DukeBox schreef op maandag 22 juli 2013 @ 16:31:
select min(date) + waarde en group by waarde
Ha, zo makkelijk had ik hem niet bedacht! Zal de warmte wel zijn :)

  • Tinuske
  • Registratie: September 2002
  • Laatst online: 26-08-2024
@DukeBox @Thrackan
Bedankt voor jullie reactie. min(date) + group by werkt uitstekend ! :)

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:03

MueR

Admin Devschuur® & Discord

is niet lief

Behalve dat je data niet klopt. Bij een "datum" van 05-01-2012 en 01-02-2012 ga je die laatste terugkrijgen, omdat je alleen tekst hebt, geen datums.

Anyone who gets in between me and my morning coffee should be insecure.


  • jeroenikke
  • Registratie: Augustus 2003
  • Laatst online: 09:36
Let ook op dat je met die query sommige aanpassingen mist:
1/1/2013 | 20
2/1/2013 | 40
3/1/2013 | 40
4/1/2013 | 60
5/1/2013 | 40
6/1/2013 | 40

Zal het volgende teruggeven met die query:

1/1/2013 | 20
2/1/2013 | 40
4/1/2013 | 60

Terwijl de waarde ook op 5/1/2013 gewijzigd is. Als de waarde enkel kan stijgen is er uiteraard geen probleem.

  • DukeBox
  • Registratie: April 2000
  • Laatst online: 18:38

DukeBox

loves wheat smoothies

Ik ben ook alleen maar uitgegaan van het voorbeeld.

Als het een temperatuur tabel is is dat wel een puntje waar je over een aantal dagen tegenaan zal lopen ;)
Wanneer het alleen maar oploopt (bijv. een kwh meter) is dat geen issue.
Uiteraard ga ik er van uit dat je column het type date is.

Zo zie je maar weer dat meer info vrij belangrijk kan zijn in een TS.

[ Voor 35% gewijzigd door DukeBox op 22-07-2013 18:58 ]

Duct tape can't fix stupid, but it can muffle the sound.


  • CaVeFiSh
  • Registratie: Januari 2005
  • Laatst online: 16-10 14:58
Ik denk dat het beter is als de TS duidelijk aangeeft wat volgens zijn structuur een mutatie is. Dus de criteria wanneer iets gekwalificeerd wordt als mutatie zijnde. Ik heb een vermoeden dat de TS doelde op een tabel waarbij de waarde alleen maar kan oplopen. In dit geval is een MIN() + group by afdoende. Maar mocht de waarde ook kunnen zakken dan zul je iets anders moeten verzinnen. Mocht je MSSQL 2012 gebruiken dan zou je eens kunnen kijken naar de LAG() en LEAD() window functies. En als je oudere versies of oracle/mysql gebruiken dan kan ik je niet adviseren want ken daarvan niet alle functies maar heb zo mijn vermoeden dat je het daar prima met een CTE kan oplossen.

http://eu.battle.net/d3/en/profile/cavefish-2679/


  • Tinuske
  • Registratie: September 2002
  • Laatst online: 26-08-2024
Ik zal iets meer info geven.
Het gaat hier om een logtabel waarin ijkingen m.b.t. een niveaumeter worden gelogd.
Datum is van het type Datetime
Waarde is van het type Float

Vaak zie je dat de waarde stijgt, maar het kan ook voorkomen dat de waarde zakt.
Logtabel zou er dus bijv. ook zo kunnen uitzien :
Datum | Waarde
01-01-2012 | 30
02-01-2012 | 30
03-01-2012 | 30
04-01-2012 | 30
05-01-2012 | 40
06-01-2012 | 40
07-01-2012 | 60
08-01-2012 | 50
09-01-2012 | 20

Goed om te lezen dat het niet werkt, bij een daling van de waardes. Hier had ik nog geen rekening mee gehouden. De database is een SQL 2012. LAG() en LEAD() functies zijn voor mij nog onbekend. Hier ga ik naar kijken. Als er iemand snel een voorbeeld voor mij heeft m.b.t. bovenstaande houdt ik me aanbevolen.

  • CaVeFiSh
  • Registratie: Januari 2005
  • Laatst online: 16-10 14:58
Tinuske schreef op dinsdag 23 juli 2013 @ 09:33:

Goed om te lezen dat het niet werkt, bij een daling van de waardes. Hier had ik nog geen rekening mee gehouden. De database is een SQL 2012. LAG() en LEAD() functies zijn voor mij nog onbekend. Hier ga ik naar kijken. Als er iemand snel een voorbeeld voor mij heeft m.b.t. bovenstaande houdt ik me aanbevolen.
Dit zou je kunnen doen:

edit: zie oplossing beneden

[ Voor 20% gewijzigd door CaVeFiSh op 24-07-2013 11:29 ]

http://eu.battle.net/d3/en/profile/cavefish-2679/


  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
Een, in mijn ogen, iets leesbaardere versie van CaVeFiSh's query:

SQL:
1
2
3
4
5
6
7
SELECT datum, waarde
FROM (
  SELECT datum, waarde, LAG(waarde) OVER (ORDER BY datum) AS prev_waarde
  FROM tabel
)
WHERE waarde <> prev_waarde
ORDER BY datum;

main = putStr (q ++ show q); q = "main = putStr (q ++ show q); q = "


  • Tinuske
  • Registratie: September 2002
  • Laatst online: 26-08-2024
Bedankt, dit werkt inderdaad goed op 1 punt na.
De 1e rij in de tabel heeft geen prev_waarde, waardoor die niet in de output komt.

Stel tabel is
Datum | Waarde
01-01-2012 | 30
02-01-2012 | 40
03-01-2012 | 40
04-01-2012 | 20

Dan krijg ik nu als resultaat
02-01-2012 | 40
04-01-2012 | 20

Terwijl het resultaat zou moeten zijn
01-01-2012 | 30
02-01-2012 | 40
04-01-2012 | 20

Is hier nog een functie/oplossing voor binnen SQL ?

  • Sikkek
  • Registratie: Maart 2004
  • Laatst online: 18:06
De documentatie raadplegen is toch niet zoveel werk?

MSDN: LAG (Transact-SQL)

Dus : Lag(waarde,1,0) gebruiken (als je zeker weet dat de eerste rij nooit 0 als waarde heeft, anders een ander getal, -1 of zo)

  • Orion84
  • Registratie: April 2002
  • Laatst online: 11:34

Orion84

Admin General Chat / Wonen & Mobiliteit

Fotogenie(k)?

Of je lost het op buiten je database, door gewoon 1 keer door je lijst met resultaten te fietsen en alle dubbelen er uit te mikken. Items efficiënt uit een lijst mikken vereist dan wel een tactische keuze voor de datastructuur. Of je moet een tweede lijst er naast houden waar je alle waardes naartoe schrijft die je wel wilt bewaren, dan kan het ook efficiënt.

[ Voor 22% gewijzigd door Orion84 op 24-07-2013 10:27 ]

The problem with common sense is that it's not all that common. | LinkedIn | Flickr


  • CaVeFiSh
  • Registratie: Januari 2005
  • Laatst online: 16-10 14:58
Uiteindelijk krijg je dus dit:

code:
1
2
3
4
5
6
SELECT Datum,Waarde
FROM (
SELECT Datum, Waarde
     ,LAG(Waarde,1,0) OVER (ORDER BY Datum) AS Mutatie
FROM Tabel ) X
WHERE Waarde <> Mutatie


Toch ben ik het wel met Orion84 eens dat het beter zou zijn als je het in de datalaag al oplost. Je zou kunnen doen wat Orion84 zegt. Of een kolom toevoegen aan de tabel waarin je alle mutaties kenmerkt bij de import/update etc. Op die manier voorkom je dat dit soort queries te zwaar gaan worden als je bijvoorbeeld door 100M aan records moet gaan.

[ Voor 64% gewijzigd door CaVeFiSh op 24-07-2013 11:42 ]

http://eu.battle.net/d3/en/profile/cavefish-2679/


  • Tinuske
  • Registratie: September 2002
  • Laatst online: 26-08-2024
Bedankt nog. Dit had ik inderdaad zelf gewoon moeten vinden.

Betreft hier een database van een leverancier, dus ga hier niets aan veranderen.
Verder gaat het om 10.000 rijen, dus daarmee wordt het niet te zwaar.

Nogmaals bedankt voor jullie hulp.
Dit is ie uiteindelijk geworden :
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
SELECT Datum, Eenheid1, Eenheid2, Eenheid3, Eenheid4, Volt1, Volt2, Volt3, Volt4
FROM
(
  SELECT 
        pr.TimeLastUpdate as Datum, 
        pa.CalInp1  as Eenheid1, 
        LAG(pa.CalInp1,1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Eenheid1,
        pa.CalInp2 As Eenheid2, 
        LAG(pa.CalInp2,1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Eenheid2,
        pa.CalInp3 As Eenheid3, 
        LAG(pa.CalInp2,1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Eenheid3,
        pa.CalInp4 As Eenheid4, 
        LAG(pa.CalInp2,1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Eenheid4,
        ROUND((pa.CalAdc1/(3276.7)),4) AS Volt1,
        LAG(ROUND((pa.CalAdc1/(3276.7)),4),1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Volt1,
        ROUND((pa.CalAdc2/(3276.7)),4) AS Volt2,
        LAG(ROUND((pa.CalAdc2/(3276.7)),4),1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Volt2,
        ROUND((pa.CalAdc3/(3276.7)),4) AS Volt3,
        LAG(ROUND((pa.CalAdc3/(3276.7)),4),1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Volt3,
        ROUND((pa.CalAdc4/(3276.7)),4) AS Volt4,
        LAG(ROUND((pa.CalAdc4/(3276.7)),4),1,0) OVER (ORDER BY pr.TimeLastUpdate ) AS prev_Volt4
FROM  TMX.tmx.Channels ch, TMX.tmx.PropChannels pr, TMX.tmx.Locations lo, TMX.tmx.PropAI pa
WHERE Ch.Id_Location = lo.ID_LOCATION
AND lo.locCode = 30
AND pr.Id_Channel = ch.ID_CHANNEL
AND ch.Channel = 1
AND ch.Exist = 1
AND (ch.Chantype =  0 )
AND pa.ID_PropChannel = pr.ID_PropChannel
) a
WHERE (         
        (Eenheid1 <> prev_Eenheid1) 
        OR (Eenheid2 <> prev_Eenheid2) 
        OR (Eenheid3 <> prev_Eenheid3) 
        OR (Eenheid4 <> prev_Eenheid4) 
        OR (Volt1 <> prev_Volt1) 
        OR (Volt2 <> prev_Volt2)  
        OR (Volt3 <> prev_Volt3) 
        OR (Volt4 <> prev_Volt4)
      )
ORDER BY Datum DESC;
Pagina: 1