[php/mysql] Ik zoek omgekeerde query

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een query gemaakt maar het resultaat is precies anders om als wat ik wil.

Situatie:
Ik heb een tabel met daarin server gegevens, wat ik wil is 1 query waarmee ik kan controleren of een server nummer vaker voorkomt of niet.

Ik heb het resultaat wel via een omweg echter ik wil dit graag in 1 query maar dat lukt me niet, dit is de query waarmee ik het juiste resultaat krijg:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$sql15 = mysql_query("
                SELECT id, server_anummer 
                FROM serverlist 
                WHERE actief='1' and managed='19'
                ");
$tot15=0;
while(list($id, $anummer) = mysql_fetch_row($sql15)) {
                $getvzlist = mysql_query("
                                        SELECT * 
                                        FROM serverlist 
                                        WHERE server_anummer = '$anummer' and actief ='1' and managed != '19' and id !='$id' 
                                       ");
                $vztotaal = mysql_num_rows($getvzlist);
                if ($vztotaal==0) { $tot15++; }
}


Dit geeft me dus exacte het juiste resultaat, nu probeer ik deze query dus wat eenvoudiger op te zetten en had deze query dus verzonnen:
PHP:
1
2
3
4
5
6
$sql15 = mysql_query("
  SELECT * 
  FROM serverlist as r, serverlist as a 
  WHERE a.server_anummer = r.server_anummer and a.id != r.id and a.actief = '1' and r.actief ='1' and a.managed != '19' and r.managed = '19' 
  ");
$tot15 = mysql_num_rows($sql15);


Deze query doet het dus ook echter met exact het omgekeerde resultaat als de eerste query.
Ik wil dus dat ie alleen selecteert als er GEEN match is.
Simpel gezegd ik wil alleen een output als het managed=19 en het anummer maar 1 keer voorkomt in de database en de waarde actief 1 is. Ik heb dus een probleem met dat 1 keer voorkomen, dat krijg ik niet eruit gefilterd.

Ik heb al diverse dingen geprobeerd maar ik zie het op dit moment niet meer.
De reden dan de eerste optie niet goed genoeg is komt doordat ik elders deze zelfde query wil gebruiken en hiermee direct alle servers wil laten zien, daar heb ik alleen de mogelijkheid om met 1 query te werken anders moet ik teveel gaan veranderen in het script.

Iemand een tip hoe ik dit met 1 query voor elkaar kan krijgen?

[ Voor 6% gewijzigd door Verwijderd op 01-01-2009 22:38 . Reden: query duidelijk geplaatst ]


Acties:
  • 0 Henk 'm!

Verwijderd

Met een sub-query de id's uit de database halen, en via (NOT) SOME/ANY, (NOT) IN, de "omgekeerde" resultaten bereiken. De tabel-gegevens zijn altijd makkelijker voor lezers om je te helpen. Evenals je query verdelen over meerdere regels. Ik lees ze niet eens :P Succes

Acties:
  • 0 Henk 'm!

Verwijderd

Je kunt hier wellicht gebruik maken van GROUP BY en HAVING. Je krijgt dan iets als:

SQL:
1
2
3
4
5
SELECT   server_anummer, COUNT(server_anummer)
FROM     serverlist
WHERE    ...
GROUP BY server_anummer
HAVING   COUNT(server_anummer) > 1


Zo krijg je alleen de server_anummers terug die meerdere keren voorkomen, met daarbij meteen het aantal keer dat ze voorkomen.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thx maar het klopt niet helemaal.

Als ik mijn query uitvoer dan is het resultaat 8, voer ik jou query uit kom ik op 0, voer ik mijn "omgekeerde" query ui is het resultaat 584
Verander ik >1 in >0 komt er als resultaat 267 uit.

Iets klopt er dus niet..

Dit is de query die ik gebruikt heb:
PHP:
1
2
3
4
5
SELECT      server_anummer, COUNT(server_anummer) 
FROM         serverlist 
WHERE      actief='1' and managed =  '19' 
GROUP BY server_anummer 
HAVING      COUNT(server_anummer) > 1


Maar wat deze query niet doet nu is dat ie alleen actief='1' en !='19' moet pakken

Dit zou een query moeten zijn maar dit is niet togestaan:
PHP:
1
2
3
4
5
$sql16 = mysql_query("
SELECT server_anummer, COUNT(server_anummer) 
FROM serverlist WHERE actief='1' and managed =  '19' 
GROUP BY server_anummer HAVING COUNT(server_anummer) > 0 and managed!='19' 
");


Iemand nog een idee?

Acties:
  • 0 Henk 'm!

  • Fish
  • Registratie: Juli 2002
  • Niet online

Fish

How much is the fish

Iperf


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
nee, als het zo makkelijk was....

Het gaat er om dat ik eerst een selectie maak, dan van het resultaat van die selectie wil ik weten als er GEEN match is!
Dus kijk maar eens goed naar de eerste query die ik gaf, die werkt, dat wil ik echter in 1 query hebben

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

.edit: nvm

[ Voor 98% gewijzigd door .oisyn op 01-01-2009 23:28 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

De makkelijkste oplossing is natuurlijk het volgende:

MySQL:
1
2
3
4
5
SELECT * FROM serverlist WHERE id NOT IN (
  SELECT r.id
  FROM serverlist as r, serverlist as a 
  WHERE a.server_anummer = r.server_anummer and a.id != r.id and a.actief = '1' and r.actief ='1' and a.managed != '19' and r.managed = '19' 
);
Overigens zou wat meer uitleg over je datamodel wel nuttig zijn; dan komt er wellicht zelfs nog een nette oplossing voorbij. Wat is je 'managed' veld; en waarom moet deze geïnverteerd worden? In je situatie omschrijving komt deze helemaal niet voor?

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • Fish
  • Registratie: Juli 2002
  • Niet online

Fish

How much is the fish

Nou lees ik wat beter, Een join naar de zelfde column? het nut ontschiet me even

[ Voor 22% gewijzigd door Fish op 02-01-2009 00:41 ]

Iperf


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Heb de queries niet gezien, ik haakte af bij $sql15.
Doe jezelf een plezier een geef je variabelen een fatsoenlijke naam :|

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Zonder verdere info over het datamodel denk ik aan zoiets:

SQL:
1
2
3
4
5
6
SELECT ... FROM tabel as a LEFT JOIN tabel as b
ON a.server_nummer=b.server_nummer (gewone join clause)
AND b.actief=1 (negeer rijen in b waar actief <> 1)
AND b.managed <> 19 (negeer rijen in b waar managed=19)
WHERE a.actief=1 AND a.managed=19
AND b.server_nummer IS NULL (nl. als  er geen resultaten in die join zitten)


nu is mijn sql een beetje roestig en zonder wat meer info over je datamodel kan ik het ook niet echt verder uitdenken. Je geeft nogal summiere informatie, en dat helpt absoluut niet :P
Bedenk ook dat een query die 'lijkt te werken' niet goed hoeft te zijn: bedenk goed welke informatie je nodig hebt en hoe je datamodel in elkaar zit. Dáármee kan je bepalen hoe de query moet werken.

offtopic:
frickY: als het echt erg is dan pak je een een Afbeeldingslocatie: http://tweakimg.net/g/forum/templates/tweakers/images/icons/icon_hand.gif, maar hier is een redelijk zinvolle discussie. Houd dat soort zinloze opmerkingen als losse post alsjeblieft achterwege...

[ Voor 15% gewijzigd door ValHallASW op 02-01-2009 00:56 ]


Acties:
  • 0 Henk 'm!

  • CMG
  • Registratie: Februari 2002
  • Laatst online: 10-12-2024

CMG

Never mind, is nog vroeg...

[ Voor 95% gewijzigd door CMG op 02-01-2009 08:20 ]

NKCSS - Projects - YouTube


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
ValHallASW schreef op vrijdag 02 januari 2009 @ 00:54:
Zonder verdere info over het datamodel denk ik aan zoiets:
...random query...
offtopic:
frickY: als het echt erg is dan pak je een een [afbeelding], maar hier is een redelijk zinvolle discussie. Houd dat soort zinloze opmerkingen als losse post alsjeblieft achterwege...
Zonder datamodel queries roepen is net zo zinloos, met het verschil dat je aan een random query helemaal geen (*&%@ hebt, en van een offtopic naamgeving hint nog wel iets kan leren. :>

Dit topic kan gewoon niet verder zonder [1] Het datamodel en [2] een duidelijker uitleg wat het gewenste resultaat is.

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het managed veld is een tiny int veld, deze kunnen waardes tussen de 1 en 30 hebben
Het actief veld idem waar geld 0 is niet actief en 1 wel actief
Het server_anummer veld is een varchar(15), dit veld is altijd iets van A1111, A283, S812 etc..

Opzet database:
In de database staan server gegevens, elke server heeft een Anummer, bv A1234
Als een server actief is, in gebruik dus dan is dezer dus 1
Met het managed veld wordt het type server gedefineerd, je hebt bv hardware nodes (=19), dit is een server die gebruikt wordt om virtuele servers te hosten.

Nu zijn er tegenwoordig ook VZ servers (virtuele servers), deze hebben geen eigen hardware maar maken dus gebruik van de hardware van een andere server, in dit geval een hardware node.
Voorbeeld
id 3 = een "echte" server en is actief (1), dit is een "hardware node" (managed=19) en heeft als nummer A1234 (=server_anummer)
id40 = een "vz" server en is ook actief(1), dit is dus een "virtuele" server (managed = 22) en staat op een echte server met nummer A1234 (=server_anummer)
id32 = is ook een "vz" server en is ook actief(1), dit is dus een "virtuele" server (managed = 13) en staat op een echte server met nummer A522 (=server_anummer)
id52 = is ook een "vz" server en is ook actief(1), dit is dus een "virtuele" server (managed = 21) en staat ook op een echte server met nummer A1234 (=server_anummer)
id 8 = een "echte" server en is actief (1), dit is een "hardware node" (managed=19) en heeft als nummer A459 (=server_anummer)

Nu wil ik dus weten of er in de databases "hardware nodes" (=managed 19) zijn waar **GEEN** virtuele servers op staan welke actief is (actief=1) Ik zoek dus een "lege" hardware node...
In bovenstaand voorbeeld moet ik als result dus alleen de server met id 8 terug krijgen, dit is een hardware node (managed 19) waar geen andere servers aan gekoppeld zijn.

Een query om te zoeken op hardware nodes met wel VZ's erop is eenvoudig omdat het Anummer matched, maar ik wil dus exact het omgekeerde....

Hopelijk is het zo iets duidelijker wat de bedoeling is.

Acties:
  • 0 Henk 'm!

  • Fish
  • Registratie: Juli 2002
  • Niet online

Fish

How much is the fish

Het idee is dat je een goede join maakt (left join) waarschijnlijk
hietbij krijg je ook de resultaat als er in de rechter kant van de join geen resultaat is (NULL)

dan zoek je op die NULL in de rechterkant, dan zou je je lege servers moeten hebben

http://www.tizag.com/mysqlTutorial/mysqlleftjoin.php

Iperf


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
OK ik heb de query nu half werkend.....

De query geeft bij een num_row het correct aantal servers aan, echter als ik daarna een while doe om de data uit diverse rijen op te halen krijg ik geen gegevens retour.

Dit is de query welke ik uiteindelijk heb gebruikt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$result = mysql_query("
SELECT * FROM serverlist as a LEFT JOIN serverlist as b 
ON a.server_anummer=b.server_anummer 
AND b.actief='1' 
AND b.managed <> '19' 
WHERE a.actief='1' and a.managed='19' 
AND b.server_anummer IS NULL
");

$totaal = mysql_num_rows($result);

echo "totaal = $totaal \n";  // dit geeft het juiste aantal terug, in deze test was dit 1

while ( $row = mysql_fetch_array($result) )
        {  
         $servid=$row["id"];
         echo "$servid \n"; //hier zou ik 1 result moeten krijgen maar krijg niets retour....
        }


iemand een idee waarom ik geen data terug krijg?

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Zowel a als b bevatten een id-veld... en jij specificeert in de query niet in welke je geinteresseerd bent, en php kan maar 1 id key in een associative array kwijt. En die van b is de laatste, dus blijkbaar krijg je die... En die is uiteraard null.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
hmmm logisch

Is er een manier dat ik ipv b a terug krijg zonder dat ik dit in de while moet gaan specificeren..

Het probleem is dat die $result = bla bla anders kan zijn gezien de keuze die je in het script elders maakt.
Ik bedoel dus:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
if ($eenwaarde==1) { 
        $result = mysql_query(" SELECT * FROM serverlist etc etc...");
}
if ($eenwaarde==2) {
       $result = mysql_query(" SELECT een heel andere query etc..");
}
if ($eenwaarde==3) etc..
while ( $row = mysql_fetch_array($result) )
        { 
        $servid=$row["id"]; 
        etc etc
}


Het zou dus handig zijn als ik dus in de query kan aangeven dat ie het van a moet nemen..

Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

is SELECT a.id AS id FROM misschien een idee; of zelfs SELECT a.* FROM? Dit zijn dan wel weer vragen van een niveau waarvan we verwachten dat je het beheerst; of zelf in de handleiding kan vinden :)

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ja inderdaad zeer dom had het zelf ook al gevonden.....
Ik had niet verwacht dat dit zou werken namelijk, dus ook niet geprobeerd....

edit:
probleem is nu opgelost, alles werkt zoals ik het wil....

[ Voor 61% gewijzigd door Verwijderd op 02-01-2009 17:15 ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Tip voor de volgende keer, benoem zelf je velden die je ophaalt en gebruik geen select *.
Scheelt wat bits over de lijn sturen en zorgt er ook voor dat je aliassen etc goed kan gebruiken...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Klopt, maar zoals ik al in mijn laatste voorbeeld aangaf zijn er diverse qeurie die gebruik maken van de zelfde while functie afhankelijk van elders in het script, elke query moet dan ook nog eens andere waardes ophalen, de select * was de beste oplossing voor dit geval.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Verwijderd schreef op vrijdag 02 januari 2009 @ 19:35:
Klopt, maar zoals ik al in mijn laatste voorbeeld aangaf zijn er diverse qeurie die gebruik maken van de zelfde while functie afhankelijk van elders in het script, elke query moet dan ook nog eens andere waardes ophalen, de select * was de beste oplossing voor dit geval.
Tja, zal aan mij liggen, maar juist in zo'n geval zou ik geen * gebruiken, maar expliciete veldnamen.
Met een * wens ik je veel succes met debuggen als je in 1 tabel je id-kolom ( of een andere kolom die je in je while gebruikt ) anders benoemt. Je query gaat dan goed alleen je while gaat dan verkeerd.

Dan heb ik meer zoiets van laat die query maar de soep indraaien, dan kijk ik tenminste gelijk in de dbase...
Pagina: 1