Select in delen splitsen

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

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Ik gebruik PHP met MySQL, en moet alle id's uit een tabel halen die voldoen aan 6 criteria. Dit vergt per criterium een select statement met een join van drie tabellen. Bijvoorbeeld een tabel grappen, met grapID's, een tabel rubrieken, en een tabel Grapzoekrubriek (combinatie grapID/rubriekID). Zo zijn er nog vijf combinaties van de grappentabel met andere zaken.
Dit heb ik met één hele lange Select-statement geprobeerd, maar ik kreeg een vage foutmelding (not a valid SQL resourse) in een regel na het uitvoeren van de query. Toen ik de select direct op de database uitvoerde kreeg ik de melding dat de query te lang zou duren, en dat als de select goed is, dit te verhelpen is met SQL_BIG_SELECTS=1.
Dat heb ik geprobeerd, maar de boel loopt vast. Daarom wil ik nu 6 query's maken en daarna de id's zoeken die in alle query's voorkomen. Hoe doe ik dat????? Ik ben geen newbee meer, maar wel een echte hobyist. ik hoop dat jullie me kunnen helpen. Oh ja, als laatste moet ik een tabel genereren met fetch-array.

Het is even een hele lap tekst :7 . Maar ik hoop dat ik duidelijk genoeg heb verteld wat mijn probleem is.

Nobody knows nothing... some of us just know very little


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
weet je zeker dat de query niet fout is? heb je print(mysql_error()) geprobeerd?

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Sorry dat ik zo laat pas reageer, was vergeten dat ik gisteravond naar een verjaardag moest :( . Ik had liever zitten programmeren maar goed. Ik echo standaard onder iedere query de foutmelding. En daaruit kwam alleen: dit-of-dat is not a valid SQL Resource value. En die fout zit niet in de query, maar in de aanroep op de regel daarna: $row=mysql_fetch_array($sql).

Pas toen ik de statement op de database intypte kreeg ik dat verhaal over een te grote query. Ik heb alles wel 10 keer gecontroleerd, maar dat geeft naar mijn ervaring niet de garantie dat er dus geen fout in zit |:( .
Het heeft denk ik weinig zin mijn script te posten, maar misschien weet toch iemand hoe ik $sql kan splitsen en dan de id's zoeken die in iedere array voorkomt?

Nobody knows nothing... some of us just know very little


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Een 'te groot SQL-statement'-melding verbaast me. Maar goed, ik heb nog nooit op een MySQL database gewerkt. Ik heb weleens queries losgelaten met 1000 or-statements erin, en die doen het gewoon op een Paradox DB-je.

Post je query eens? (Tabelstructuur d'r bij??)

Siditamentis astuentis pactum.


  • PhoeniX-
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:30
als er zoiets staat als 'is not a valid mysql resource' dan betekent dat in principe toch dat er geen resultaten uit de db zijn komen rollen? Dus of de query is fout, of het levert geen results op.

Als je zo'n query opstelt met (php) variabelen (bv : select * from lala where id=$bla), probeer dan eens een echo $query .. dit helpt mij vaak wel (-:

deze query kan je dan bijvoorbeeld even copy / pasten naar een phpMyAdmin oid .. En ik heb idd ook nog nooit zo'n foutmelding gehad ..

Maar splitsen moet idd mogelijk zijn, maar lijkt me niet al te efficient / netjes

  • Rense Klinkenberg
  • Registratie: November 2000
  • Laatst online: 23:45
Op woensdag 23 januari 2002 10:07 schreef PhoeniX- het volgende:
als er zoiets staat als 'is not a valid mysql resource' dan betekent dat in principe toch dat er geen resultaten uit de db zijn komen rollen? Dus of de query is fout, of het levert geen results op.
Nee een error '... is not a valid MySQL resource' betekend heel simpel dat de string geen mysql resource is (idd. best wel duh. ;))

Dit heeft niets te maken met of er wel of geen resultaten zijn, die uit de query komen, maar of de query überhaupt wel gewerkt heeft.

Een stukje manual:
Only for SELECT statements mysql_query() returns a resource identifier or FALSE if the query was not executed correctly. For other type of SQL statements, mysql_query() returns TRUE on success and FALSE on error. A non-FALSE return value means that the query was legal and could be executed by the server. It does not indicate anything about the number of rows affected or returned. It is perfectly possible for a query to succeed but affect no rows or return no rows.
Als je een var_dump zal doen van de variabele, zal je ook zien dat het een boolean is met waarde false.

't komt er dus gewoon op neer dat de query niet goed is.

  • PhoeniX-
  • Registratie: Juni 2000
  • Laatst online: 15-09 11:30
humzz

je hebt helemaal gelijk, ik zat fout wat dat betreft .. geen idee waar ik dat dan vandaan heb gehaald (-:

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Bedankt alvast voor jullie reacties. Vanavond post ik een stukkie van mijn script, en de reactie van de db. Nu zit ik op mijn werk (ik ben metallurg, en hobby met mysql in de avonden). Dus tot die tijd kan ik niets posten.

Maar stel nou dat ik die query toch moet opsplitsen, en php de gemene deler moet laten bepalen en dan in een tabel weergeven. Hoe doe ik dat dan? Ik heb iets geprobeerd met enkele query's, en dan (ff uit mijn blote bol weet ik niet meer hoe die functie heet)
$grappen = array_intersect ($sql1, $sql2,...);
$grap = mysql_fetch_array($grappen);

maar nu heb ik een parse error op de fetch_array-regel, ben er nog niet achter wat er mis mee is.

Nobody knows nothing... some of us just know very little


  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Ben ik weer.Mijn script ziet er ongeveer zo uit:
<?php
$from='Grappen AS G';//begin van de query
$where='G.ID>0'; //begin van de where-clausule
if ($rid!=""){
$from.=" , Grappen AS GR, Grapzoekrubriek AS GzR";
$where.=" AND GR.ID = GzR.ID AND GzR.RID='$rid'";
}
?>
dan wat herhalingen voor de auteur en de tekst die de grap moet bevatten. Daarna de statement:
<?php
$grappen=mysql_query("SELECT G.ID FROM $from WHERE $where ");
echo("<pre> SELECT G.ID FROM $from WHERE $where <Br>var_dump:");
var_dump($grappen);
echo("<Br>mysql_error() <Br></pre>");
while ($grap=mysql_fetch_array($grappen))//<----DIT IS REGEL 67!!
// tabel opbouwen ,et grap-nummers
?>

Wat er vervolgens op het scherm komt ziet er als volgt uit:
SELECT G.ID FROM Grappen AS G , Grappen AS GR, Grapzoekrubriek AS GzR , Grappen AS GA, Grapzoekauteur AS GzA WHERE G.ID>0 AND GH.ID = GzR.ID AND GzR.RID='47' AND GA.ID = GzA.ID AND GzA.AID='28' AND G.Tekst LIKE '%Er was eens een man%'

var_dump: bool(false)

mysql_error():
Warning: Supplied argument is not a valid MySQL result resource in /www/blijf-aktief/bewerkveelprods.php on line 67

Als ik de select-statement op de database zelf invoer dan krijg ik dit:
ERROR 1104: The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET OPTION SQL_BIG_SELECTS=1 if the SELECT is ok
mysql>

Omdat dus de query om de één of andere reden te groot wordt bevonden, voert hij hem niet uit, daarom var_dump($grappen_ ->FALSE en vervolgens kan 'fetch_array' niet uitgevoerd worden.
Kan iemand me helpen?

Nobody knows nothing... some of us just know very little


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
code:
1
echo("<Br>mysql_error() <Br></pre>");

daarmee print je letterlijk 'mysql_error()', dat heeft natuurlijk niet veel nut :)

probeer het eens zo:
code:
1
echo("<Br>" . mysql_error() . "<Br></pre>");

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Klopt, ;) dat doe ik ook alleen om aan te geven dat daar de daarop volgende tekst vandaan komt.
Warning: Supplied argument is not a valid MySQL result resource
in /www/blijf-aktief/bewerkveelprods.php on line 67

Nobody knows nothing... some of us just know very little


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
[edit]
oeps, foutje.

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
geef nie! :)
;( Ik hoop alleen dat mijn gevalletje hoog genoeg blijft staan zodat er nog iemand met een reactie komt!

Nobody knows nothing... some of us just know very little


  • Martijn02
  • Registratie: September 2000
  • Laatst online: 15-09 14:25

Martijn02

/* No Comment */

Yow, daar ben ik al... :)

Hmmm, eens even kijken... Je query levert inderdaad nog al wat rijen op, dit komt omdat hij volgens mij niet zo slim in elkaar zit. Om eerlijk te zijn is het niet helemaal duidelijk wat je nou wil, maar zal in ieder geval proberen uit te leggen waarom de oplossing die je hebt gekozen niet werkt.
code:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT G.ID 
FROM Grappen AS G,
     Grappen AS GR,
     Grappen AS GA,
     Grapzoekrubriek AS GzR,
     Grapzoekauteur AS GzA
WHERE G.ID>0
  AND GH.ID = GzR.ID 
  AND GzR.RID='47' 
  AND GA.ID = GzA.ID 
  AND GzA.AID='28' 
  AND G.Tekst LIKE '%Er was eens een man%'

Ik heb geprobeerd je query een beetje leesbaarder neer te zetten, als je te tabellen op deze manier join worden eerst iedere rij uit iedere tabel aan iedere rij aan iedere tabel gekoppelt...

Dus, stel: Grappen heeft 100 records, Grapzoekrubriek heeft er 20 (ik roep maar wat) en Grapzoekauteur heeft er ook 20 (zijn toch geen extreme getallen, wel?)

Nu worden er 100 x 100 x 100 x 20 x 20 = 400.000.000 records geformuleerd die allemaal door de where statements behandeld moeten worden. Lijkt me niet vreemd dat je database dan even tegensputtert (eigenlijk vind ik dat het ding gewoon moet doen wat je hem opdraagt, en niet moet lopen zeiken, maar aan de andere kant ben je niet zo heel erg slim bezig, dus ok...)

Neem nou bijvoorbeeld dit stukje
code:
1
     Grappen AS GR,

Allereerst waarom koppel je de tabel aan zich zelf? wat wil je er mee berijken? en daarna noem je het ding GR, maar die gebruik je verder niet meer in je query.
code:
1
WHERE G.ID>0

Ik weet niets van je structuur hoor, maar heb je ook records met een ID <=0 in je database zitten? Geen commentaar, maar dit is niet echt gebruikelijk
code:
1
  AND GH.ID = GzR.ID

Waar haal je die GH vandaan? of is dat soms die GR van hierboven? typo dus?

Nouja, voorlopig kan ik ff niet zo veel zeggen... post je tabelstructuur eventjes, welke velden zitten er in welke tabellen, en probeer uit te leggen wat je nou precies met die query wil.

Dan kijk ik of ik je nog een beetje verder kan helpen

  • Martijn02
  • Registratie: September 2000
  • Laatst online: 15-09 14:25

Martijn02

/* No Comment */

Leuk jezelf quoten :)
Op donderdag 24 januari 2002 10:23 schreef Martijn02 het volgende:
Dus, stel: Grappen heeft 100 records, Grapzoekrubriek heeft er 20 (ik roep maar wat) en Grapzoekauteur heeft er ook 20 (zijn toch geen extreme getallen, wel?)

Nu worden er 100 x 100 x 100 x 20 x 20 = 400.000.000 records geformuleerd die allemaal door de where statements behandeld moeten worden. Lijkt me niet vreemd dat je database dan even tegensputtert
ik zag net dat je de tabellen Grapzoekrubriek, Grapzoekauteur en Grappen 1 op 1 aan elkaar koppelt, mijn berekening wordt dus nog iets extremer als Grapzoekrubriek en Grapzoekauteur geen 20 maar 100 rijen hebben..

100 x 100 x 100 x 100 x 100 = 100^5 = 10.000.000.000 (10 miljard)

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
OK, ben misschien niet slim bezig, maar ik zal uitleggen waarom ik doe wat ik doe. Ondanks je niet al te vriendelijke opmerkingen, aangaande mijn grijze cellen: toch bedankt dat jij in ieder geval ff tijd voor me vrij wilt maken!
Ten eerste: ja GH is een typo, moet zijn GR.

Ten tweede: ik heb mijn (geringe)php-kennis uit een boek, en daar staat vermeld dat als je één colom uit een tabel wilt joinen aan colommen in meerdere andere tabellen, je gebruik moet maken van aliasing, om te voorkomen dat één veld aan meerdere criteria tegelijk wordt onderworpen.

Ten derde: G.ID>0 is natuurlijk een 'beginwaarde' zodat als er dus geen zoekcriteria opgegeven worden, ik toch nog wat in het where-deel van de statement heb staan.

De tabelstructuur is als volgt:
Grappen:_________[ID][Tekst] (Primary key=ID)
Rubrieken:_______[RID][Rubriek](Primary key=RID)
Auteurs:_________[AID][Auteur][e-mail adres][password](Primary key=AID)
Grapzoekrubriek:_[ID][RID](Primary key=ID,RID)
Grapzoekauteur:__[ID][AID](Primary key=ID,AID)

Ik hoop dat iemand nogmaals mee wil denken. Vanavond zal ik het eens zonder aliasing proberen, dat zou volgens bovenstaande theorie 20.000 regels schelen!

Nobody knows nothing... some of us just know very little


  • Martijn02
  • Registratie: September 2000
  • Laatst online: 15-09 14:25

Martijn02

/* No Comment */

Op donderdag 24 januari 2002 11:01 schreef Steam het volgende:
OK, ben misschien niet slim bezig, maar ik zal uitleggen waarom ik doe wat ik doe. Ondanks je niet al te vriendelijke opmerkingen, aangaande mijn grijze cellen: toch bedankt dat jij in ieder geval ff tijd voor me vrij wilt maken!
No offence, is absoluut niet lullig bedoeld, iedereen is ooit een n00b geweest.
Ten eerste: ja GH is een typo, moet zijn GR.

Ten tweede: ik heb mijn (geringe)php-kennis uit een boek, en daar staat vermeld dat als je één colom uit een tabel wilt joinen aan colommen in meerdere andere tabellen, je gebruik moet maken van aliasing, om te voorkomen dat één veld aan meerdere criteria tegelijk wordt onderworpen.
dat aliaising klopt bij deze manier van joinen, maar je kan beter gebruik maken van een andere manier van joinen (leg ik zo uit)
Ten derde: G.ID>0 is natuurlijk een 'beginwaarde' zodat als er dus geen zoekcriteria opgegeven worden, ik toch nog wat in het where-deel van de statement heb staan.
Ik snap dat het vanuit het script mischien makkelijker is om op deze manier een query te bouwen, maar hij moet wel voor iedere rij gecontroleerd worden 10 miljard keer een kleine controle kan toch best lang duren.
De tabelstructuur is als volgt:
Grappen:_________[ID][Tekst] (Primary key=ID)
Rubrieken:_______[RID][Rubriek](Primary key=RID)
Auteurs:_________[AID][Auteur][e-mail adres][password](Primary key=AID)
Grapzoekrubriek:_[ID][RID](Primary key=ID,RID)
Grapzoekauteur:__[ID][AID](Primary key=ID,AID)

Ik hoop dat iemand nogmaals mee wil denken. Vanavond zal ik het eens zonder aliasing proberen, dat zou volgens bovenstaande theorie 20.000 regels schelen!
geen 20.000 regels, veel meer...

Zit even te kijken naar je tabelstructuur...
Als je je code tussen "[ code ]" en "[ /code ]" (zonder spaties) zet, dan is het wat beter leesbaar.

Het nut van de eerste 3 tabellen is te begrijpen, de laatste 2 echter zie ik niet zo, waarom gebruik je daar koppeltabellen? Is het zo dat er meerdere auteurs bij een grap horen, of dat een grap onder meerdere categorien valt?

Het zou een stuk simpeler zijn om in de grap een verwijzing naar de auteur (is er immers maar een) op te nemen, en een verwijzing naar de categorie. je stuctuur wordt dan als volgt:
code:
1
2
3
Grappen:_________[ID][Tekst][rubriekID][auteurID]
Rubrieken:_______[ID][naam]
Auteurs:_________[ID][naam][email][password]

In alle gevallen is de ID de primary key...

Als je nu een zoekpagina maakt met daarop een textveld ($text) en 2 dropdowns waar de rubrieken en auteurs in staan ($rubriekID en $auteurID) Kan je je query als volgt opbouwen
code:
1
2
3
4
5
6
7
SELECT * 
FROM Grappen
LEFT JOIN Rubrieken ON Grappen.rubriekID = Rubrieken.ID
LEFT JOIN Auteurs ON Grappen.auteurID = Auteurs.ID
WHERE Grappen.text LIKE "%$text%"
  AND Grappen.rubriekID = $rubriekID
  AND Grappen.auteurID = $auteurID

en nu kan je als de $rubriekID, of de $auteurID NULL of 0 is (0 = alle auteurs/rubrieken) de regel waar ze in voorkomen altijd weglaten.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?
$SQL = "FROM Grappen
        LEFT JOIN Rubrieken ON Grappen.rubriekID = Rubrieken.ID
        LEFT JOIN Auteurs ON Grappen.auteurID = Auteurs.ID
        WHERE Grappen.text LIKE '%$text%'";

if (isset($rubriekID) &amp;&amp; is_numeric($rubriekID) &amp;&amp; $rubriekID)
    $SQL .= "  AND Grappen.rubriekID = $rubriekID";

if (isset($auteurID) &amp;&amp; is_numeric($auteurID) &amp;&amp; $auteurID)
    $SQL .= "  AND Grappen.auteurID = $auteurID";
// en dan voer je je query uit enzo
?>

Lukt het zo denk je? Veel succes!

  • Steam
  • Registratie: Juli 2001
  • Laatst online: 26-11-2021

Steam

just getting there

Topicstarter
Ga ik proberen.
:+ bedankt!

Nobody knows nothing... some of us just know very little

Pagina: 1