SQL: WHERE-clausule zorgt voor NULL-waarden in andere kolom

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • Bastiaan
  • Registratie: November 2002
  • Laatst online: 00:00

Bastiaan

Bas·ti·aan (de, m)

Topicstarter
Ik heb de volgende query:
code:
1
2
3
4
5
6
7
8
9
SELECT      DATE_FORMAT(table.datum, '%Y-%m') AS 'periode',
            SUM(table.waardeA) AS 'waardeA_sum',
            SUM(table.waardeB) AS 'waardeB_sum',
            SUM(table.waardeC) AS 'waardeC_sum'
FROM        table
WHERE       datum>='$startdatum' 
            AND datum<='$einddatum'
GROUP BY    periode
ORDER BY    periode ASC

Deze telt van verschillende ingevoerde waarden het één en ander op en spuugt deze uit in een tabel, gegroepeerd in maandelijkse perioden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
datum       waardeA_sum waardeB_sum waardeC_sum
2015-01     654         1234        NULL
2015-02     654         1234        123
2015-03     654         1234        123
2015-04     654         1234        NULL
2015-05     654         1234        NULL
2015-06     654         1234        123
2015-07     654         1234        NULL
2015-08     654         1234        NULL
2015-09     654         1234        NULL
2015-10     654         1234        NULL
2015-11     654         1234        NULL
2015-12     654         1234        NULL
2016-01     654         1234        123
2016-02     654         1234        123
2016-03     654         NULL        NULL

Nu wil ik dat de laatste regel (periode 2016-03) pas zichtbaar is op het moment dat in de brondata waardeB en/of waardeC ergens zijn ingevuld, en dús de uitkomst van de respectievelijke periode/kolom op iets anders dan NULL uitkomt. Dan zou je dus zeggen dat ik de WHERE-clausule aan moet vullen naar (regel 6):
code:
1
2
3
4
5
6
7
8
9
10
SELECT      DATE_FORMAT(table.datum, '%Y-%m') AS 'periode',
            SUM(table.waardeA) AS 'waardeA_sum',
            SUM(table.waardeB) AS 'waardeB_sum',
            SUM(table.waardeC) AS 'waardeC_sum'
FROM        table
WHERE       (waardeB IS NOT NULL OR waardeC IS NOT NULL)
            AND datum>='$startdatum' 
            AND datum<='$einddatum'
GROUP BY    periode
ORDER BY    periode ASC

...maar nu krijg ik vervolgens niets in waarden terug voor waardeA:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
datum       waardeA_sum waardeB_sum waardeC_sum
2015-01     NULL        1234        NULL
2015-02     NULL        1234        123
2015-03     NULL        1234        123
2015-04     NULL        1234        NULL
2015-05     NULL        1234        NULL
2015-06     NULL        1234        123
2015-07     NULL        1234        NULL
2015-08     NULL        1234        NULL
2015-09     NULL        1234        NULL
2015-10     NULL        1234        NULL
2015-11     NULL        1234        NULL
2015-12     NULL        1234        NULL
2016-01     NULL        1234        123
2016-02     NULL        1234        123

(Maar de laatste regel is weg, dat dan weer wel...) :+

Ik krijg totaal niet de vinger achter wat dit nu veroorzaakt. Het maakt geen verschil of ik de WHERE-clausule in een andere volgorde pak, bijvoorbeeld.

Wanneer ik rondkijk op Google en/of Stack Overflow krijg je wel resultaten over hoe je NULL-waarden an sich kunt aanpakken, maar een vergelijkbaar probleem over hoe een hele kolom naar NULL springt door een clausule welke juist van toepassing op andere kolommen vind ik niet terug.

Wat zie ik nu over het hoofd? En is mijn denkwijze überhaupt de juiste?

Beste antwoord (via Bastiaan op 30-03-2016 19:55)


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Gebruik een HAVING clause ipv het in je WHERE clause te zetten.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Alle reacties


Acties:
  • 0 Henk 'm!

  • RusFighter
  • Registratie: December 2007
  • Laatst online: 11-09 15:38
Probeer iets van


SELECT *
FROM nieuwTabel
WHERE (waardeB IS NOT NULL AND waardeC IS NOT NULL) IN
(je eerste query)

Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Gebruik een HAVING clause ipv het in je WHERE clause te zetten.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Bastiaan
  • Registratie: November 2002
  • Laatst online: 00:00

Bastiaan

Bas·ti·aan (de, m)

Topicstarter
RobIII schreef op woensdag 30 maart 2016 @ 19:47:
Gebruik een HAVING clause ipv het in je WHERE clause te zetten.
Dat was 'm inderdaad:
code:
1
2
3
4
5
6
7
8
9
10
SELECT      DATE_FORMAT(table.datum, '%Y-%m') AS 'periode',
            SUM(table.waardeA) AS 'waardeA_sum',
            SUM(table.waardeB) AS 'waardeB_sum',
            SUM(table.waardeC) AS 'waardeC_sum'
FROM        table
WHERE       datum>='$startdatum' 
            AND datum<='$einddatum'
GROUP BY    periode
HAVING      waardeB_sum > '0' OR waardeC_sum > '0'
ORDER BY    periode ASC

En nu ik daarmee gerichter kan zoeken is het 'waarom' ook gelijk een stuk duidelijker:
WHERE is applied before GROUP BY, HAVING is applied after (and can filter on aggregates).
Dank je! :)