[SQL]Records ophalen die niet een bepaalde waarde hebben

Pagina: 1
Acties:
  • 195 views sinds 30-01-2008
  • Reageer

  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 04-02 17:31
Hallo allemaal,

Ik ben bezig een SQL querie te maken om data op te halen uit een database. De data die ik op moet halen moet uit 4 tabellen komen:

* Mijlpalen
* DeelProject
* Project
* Project Properties

Eerst moet ik de gegevens ophalen van projecten met een project propertie "Rayon" wat een bepaalde waarde heeft. Dit lukt allemaal wel. Maar nu komt het lastige, Vervolgens moet ik de ID's van de records die ik opgehaald heb gebruiken in een querie die alle records ophaalt die een bepaald Project Propertie NIET hebben.

Hiervoor heb ik de volgende SQL:

code:
1
2
3
4
5
6
7
8
9
SELECT pp.fk_enum_domain_project_properties, fk_deelproject, p.projectnummer, dp.volgnr,
p.omschrijving, dp.standaarddrop, m.id, m.fk_domain_datefield, m.dgeplanned,
m.dwerkelijk, p.id as fk_project FROM mijlpalen as m
inner join deelproject as dp on dp.id=m.fk_deelproject
inner join project as p on p.id=dp.fk_project
inner join project_properties as pp on pp.fk_project=p.id
WHERE p.id IN(een hoop id's)
AND (pp.fk_enum_domain_project_properties<>225 AND pp.value<>'on')
ORDER BY p.projectnummer, m.fk_deelproject, fk_domain_datefield


Alleen haalt deze sql ook records op die project propertie 225 en waarde on WEL hebben. Hoe kan ik dit in SQL oplossen? Of is dat niet mogelijk?

Per project is er 1 record in de Project tabel en meerdere in de project properties tabel. Propertie 225 is een boolean veld, als de waarde True is dan bestaat er een record voor in de project properties tabel en is het False dan bestaat er geen record voor in de project properties tabel

[ Voor 16% gewijzigd door urk_forever op 18-09-2006 16:41 ]

Hail to the king baby!


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Even zo vlug bekeken zit je fout hier:
SQL:
1
AND (pp.fk_enum_domain_project_properties<>225 AND pp.value<>'on')

Volgens mij zoek je dit:
SQL:
1
AND Not (pp.fk_enum_domain_project_properties=225 AND pp.value='on')


Simpele booleaanse algebra ;)

[ Voor 9% gewijzigd door RobIII op 18-09-2006 16:49 ]

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


  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 04-02 17:31
Helaas niet, dan haalt hij nog steeds het record op wat hij weg zou moeten laten.

Hail to the king baby!


Verwijderd

code:
1
AND (pp.fk_enum_domain_project_properties<>225 AND pp.value<>'on')

opsplitsen in
code:
1
2
AND (pp.fk_enum_domain_project_properties<>225)
AND (pp.value<>'on')

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Verwijderd schreef op maandag 18 september 2006 @ 16:58:
code:
1
AND (pp.fk_enum_domain_project_properties<>225 AND pp.value<>'on')

opsplitsen in
code:
1
2
AND (pp.fk_enum_domain_project_properties<>225)
AND (pp.value<>'on')
Behalve het verplaatsen van haakjes veranderd dit de betekenis van de expressie niet. Voegt dus niets toe.

@TS:
Je zult vrees ik met een subquery moeten werken. Een exists lijkt me in deze wel een goede.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT pp.fk_enum_domain_project_properties, fk_deelproject, p.projectnummer, dp.volgnr,
p.omschrijving, dp.standaarddrop, m.id, m.fk_domain_datefield, m.dgeplanned,
m.dwerkelijk, p.id as fk_project FROM mijlpalen as m
inner join deelproject as dp on dp.id=m.fk_deelproject
inner join project as p on p.id=dp.fk_project
inner join project_properties as pp on pp.fk_project=p.id
WHERE p.id IN(een hoop id's)
AND NOT EXISTS (
   SELECT 'X' FROM project_properties as pp1 
   WHERE pp1.fk_project=p.id
   AND pp1.fk_enum_domain_project_properties = 225
   AND pp1.value = 'on'
)
ORDER BY p.projectnummer, m.fk_deelproject, fk_domain_datefield

  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 04-02 17:31
Subquery's heb je toch niet in MySQL 4??

Hail to the king baby!


  • bazkar
  • Registratie: Juni 2001
  • Laatst online: 05-02 12:59
Wat jij wilt is dus een left join.

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT pp.fk_enum_domain_project_properties, fk_deelproject, p.projectnummer, dp.volgnr,
p.omschrijving, dp.standaarddrop, m.id, m.fk_domain_datefield, m.dgeplanned,
m.dwerkelijk, p.id as fk_project 
FROM mijlpalen as m
INNER JOIN deelproject as dp on dp.id=m.fk_deelproject
INNER JOIN project as p on p.id=dp.fk_project
INNER JOIN project_properties as pp on pp.fk_project=p.id
LEFT JOIN project as p2 on p2.id = p.id
INNER JOIN  project_properties as pp2 on pp2.fk_project=p2.id
WHERE p.id IN(een hoop id's)
AND pp2.fk_enum_domain_project_properties=225 
AND pp2.value='on'
AND p2.id IS NULL
ORDER BY p.projectnummer, m.fk_deelproject, fk_domain_datefield

oftewel, selecteer alle projecten die de property WEL hebben (p2), knoop daar ALLE projecten (p) aan met een left join en kijk vervolgens welke er NIET in p2 zitten door op p2.id IS NULL te checken.

[ Voor 3% gewijzigd door bazkar op 18-09-2006 18:25 ]


  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 04-02 17:31
Ik ben er nog even mee bezig geweest en heb het wat eenvoudiger gemaakt:

code:
1
2
3
4
5
6
7
SELECT p.id, pp.fk_enum_domain_project_properties, pp.value
FROM project as p
inner join project_properties as pp on pp.fk_project=p.id
left join project_properties as pp1 on pp1.fk_project=p.id
WHERE p.id IN(een hoop id's)
and pp1.fk_enum_domain_project_properties=225
ORDER BY p.projectnummer


Ik haal dus alle projecten met hun properties op, en daar hang ik via een left join de project properties aanvast die 225 zijn, en dan kijk ik of pp1.fk_project null is. Maar dit geeft 0 records terug, wat doe ik nog fout??

Hail to the king baby!


  • bazkar
  • Registratie: Juni 2001
  • Laatst online: 05-02 12:59
Dat vereenvoudigen wat je beschrijft levert een andere query op als die je weergeeft (ik mis de NULL clause daar bijvoorbeeld).
Ik heb nog eens naar mijn query gekeken, maar wat die uiteindelijk oplevert zijn alle projecten die minimaal 1 property anders dan 225 hebben. Nog niet wat je wilt dus. 8)7

Om de code zonder haakjes en duidelijk te houden moet de conditie in de join gepropt worden en de join omgedraaid tot een right join

SQL:
1
2
3
4
5
6
7
8
SELECT p2.id, pp2.fk_enum_domain_project_properties, pp2.value
FROM project AS p1
INNER JOIN project_properties AS pp1 ON pp1.fk_project=p1.id AND pp1.fk_enum_domain_project_properties=225
RIGHT JOIN project AS p2 ON p2.id=p1.id
INNER JOIN project_properties as pp2 on pp2.fk_project=p2.id 
WHERE p2.id IN(een hoop id's)
AND p1.id IS NULL
ORDER BY p2.projectnummer


Breakdown:
Selecteer alle projecten, join daar de project properties aan voor alle 225 properties (je hebt nu een lijst met alleen die projecten die 225 hebben). Right join daar alle projecten aan, dit levert je een uitbreiding van de lijst met NULL regels voor tabellen p1 en pp1 voor projecten die NIET 225 hebben.
Join hier tenslotte de pp2 properties aan en selecteer alleen de NULL regels.
Pagina: 1