[PHP/SQL]waarde zoeken over variable aantal kollommen

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Eerder heb ik eens een topic geopend met een gelijkaardige vraag maar toen had ik me nog niet verdiept in de beschikbare info op het web, na enig zoekwerk kom ik er deels uit maar niet helemaal.

Momenteel heb ik hetvolgende PHP/SQL script:
-------------------------
query = "SELECT * FROM Takenlijst Where Bijnaam1= 'Jan' OR Bijnaam2 = 'Jan' OR Bijnaam3 = 'Jan' OR...OR Bijnaam99 = 'Jan' ORDER BY ID"

$result = mysql_query($query);
------------------------
Kort samengevat ik zoek de waarde 'Jan' in de tabel Takenlijst. 'Jan' kan slecht 1 keer per rij maar wel in meerdere rijen voorkomen. Nu zijn naam staat ergens willekeurig in de tabel daarmee bedoel ik niet altijd in de kolom Bijnaam1 maar ook bv in kolom bijnaam23 of zelfs in kolom bijnaam99.

Nu wil ik vermijden dat ik die 99 kolommen moet opsommen aangezien ik soms wil zoeken over alle 99 kolommen maar soms ook op de eerste X kolommen.

Kan er iemand mij helpen?

Alvast hartelijk bedankt,

Indien ik deze topic nog niet volgende de regels van het forum heb opgesteld, gelieve mij te informeren want het is zeker niet zo bedoeld.

Greetz
Christophe

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Ten eerste lijkt je datamodel verkeerd ingericht, maar dit is een ander verhaal. Wat betreft je vraag: dan maak je toch verschillende (dynamische) queries afhankelijk van de eis? Te denken valt aan een array met de kolomnamen en handige php arrayfuncties gebruiken om een bepaald aantal kolommen te pakken en vervolgens de array imploderen en in de query zetten.

Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 12:47

Dido

heforshe

Ik zou maar een tabel Bijnamen maken, met daarin een Id dat verwijst naar 1 Id in je Takentabel.

Je kunt dan eenvoudig zoeken met iets als
code:
1
2
3
4
SELECT T.* 
  FROM Takenlijst T
  JOIN Bijnamen B on B.Id = T.Id
 WHERE T.Bijnaam = 'Jan';

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Als je werkelijk 99 kolommen in een tabel hebt zul je alle kolommen moeten noemen waar die waarde in voor kan komen. Je kunt de query vrij eenvoudig door PHP laten genereren zodat je niet alle kolomnamen hoeft in te tikken.

Ik zou overigens wel eerst naar de structuur van de tabel kijken. Wat voor gegevens wil je precies opslaan?

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • McKaamos
  • Registratie: Maart 2002
  • Niet online

McKaamos

Master of the Edit-button

Waarom voeg je niet alle bijnamen samen in 1 kolom? gescheiden door comma's ofzo, en dan met PHP explode() functie alle namen in een array smijten, en die met een foreach loopje doorlopen?

Iemand een Tina2 in de aanbieding?


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor de commentaren, sommige al iets bruikbaarder dan andere maar dat komt doordat ik echt nog een leek ben in het werken met PHP/SQL/programmeren in het algemeen.

Toch wilde ik achterhalen waar mijn fouten zitten:
1. BalusC: Vanwaar je vermoeden dat het datamodel verkeerd zit? Dynamische queries en arrays zijn nog geen echt vertrouwde termen voor mij. Heb ze al eens proberen te analyseren maar geraak er nog niet wijzer uit.

2.Dido: De bijnaam is in feite de id die verwijst naar de tabel Namen. Nu om het voorbeeld niet te ingewikkeld te maken heb ik even die stap overgeslagen. Dus je voorbeeld scriptje is meer dan welkom alhoewel ik denk dat je dan meerdere ID kollommen zult hebben in tabel takenlijst waardoor het dus niet handiger is en we in dezelfde situatie terecht komen als mijn voorbeeldje.

3. Icelus: Om een overzicht te geven van de structuur kan ik je zeggen dat ik werk met 3 verschillende tabellen (1: Taak, 2: Namen, 3:Takenlijst). De takenlijst bevat dus een taak en linkt die taak met x-aantal medewerkers welke gelinkd worden met tabel namen door een bijnaam. Indien dit niet de structuur is die jij zou gebruiken, hoor ik het graag.

4. Mckaamos: zoals eerder gezegd, ik ben nog maar een beginneling in het programmeren en dit was voor mij de eenvoudigste oplossing. Het script waar ik naar verwijs zal gebruikt worden om een overzicht per medewerker te kunnen geven van de taken waarvoor hij ingeschreven is. Nu een andere manier om de takenlijst te beheren zou zijn dat ik namen kan toevoegen/ verwijderen zonder lege kolommen te hebben. Deze script heb ik reeds en werken. Ik ga niet zeggen dat het script perfect is maar deze zet ik laten nog wel eens op het forum om te zien waar er verbeteringen kunnen aangebracht worden.

Alle hulp/commentaar is welkom.

greetz
Christophe

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

@McKaamos:
Komma gescheiden is net zo fout als als de genummerde kolomen van de topicstarter. Sterker nog, kommagescheiden is nog een stuk lastiger aangezien je daar een stuk lastiger met SQL op kunt query-en.

@Topicstarter:
Negeer ajb het advies van McKaamos. Wat je hier hebt is een zogenaamde 1:N relatie. Je hebt 1 persoon die meerdere bijnamen heeft. In een database los je dat als volgt op:

Tabel Persoon
persoon_id
naam

Tabel Bijnaam
bijnaam_id
persoon_id
bijnaam

Hierbij verwijst persoon_id in de tabel bijnaam naar persoon_id in de tabel persoon. Middels joins kun je deze tabellen vervolgens weer aan elkaar koppelen.

@BalusC: Ja, overmatig Copy paste is niet goed :)

[ Voor 58% gewijzigd door Janoz op 03-11-2006 09:48 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 12:47

Dido

heforshe

Verwijderd schreef op vrijdag 03 november 2006 @ 09:20:
2.Dido: De bijnaam is in feite de id die verwijst naar de tabel Namen. Nu om het voorbeeld niet te ingewikkeld te maken heb ik even die stap overgeslagen. Dus je voorbeeld scriptje is meer dan welkom alhoewel ik denk dat je dan meerdere ID kollommen zult hebben in tabel takenlijst waardoor het dus niet handiger is en we in dezelfde situatie terecht komen als mijn voorbeeldje.

3. Icelus: Om een overzicht te geven van de structuur kan ik je zeggen dat ik werk met 3 verschillende tabellen (1: Taak, 2: Namen, 3:Takenlijst). De takenlijst bevat dus een taak en linkt die taak met x-aantal medewerkers welke gelinkd worden met tabel namen door een bijnaam. Indien dit niet de structuur is die jij zou gebruiken, hoor ik het graag.
Ah, kijk :)

Daar zit dus 1 fout in je datamodel.

Je hebt een taak, je hebt namen.

In je takenlijst wil je dan alleen een koppeling leggen tussen 1 naam en 1 taak!

Alle informatie over een taak staat immers in je tabel Taak, alle info over personen in de tabel Naam, en het enige waar je de tabel takenlijst voor hoeft te gebruiken is een koppeling van personen aan taken. Als dit niet het geval is, raadt ik je aan om het aan te passen ;)

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Verwijderd schreef op vrijdag 03 november 2006 @ 09:20:
1. BalusC: Vanwaar je vermoeden dat het datamodel verkeerd zit?
99 kolommen voor 1 doel .. Dit kan veel beter in 2 kolommen :)
Dynamische queries en arrays zijn nog geen echt vertrouwde termen voor mij. Heb ze al eens proberen te analyseren maar geraak er nog niet wijzer uit.
Met "dynamisch" bedoel ik dat je met PHP runtime een query samenstelt op basis van de eisen in plaats van om met de hand neer te tikken (statisch). En over array's is genoeg te vinden in de PHP tutorials en de uitstekende documentatie op php.net.
Janoz schreef op vrijdag 03 november 2006 @ 09:22:
@Topicstarter:
Negeer ajb het advies van Aangezien je een McKaamos.
8)7

[ Voor 12% gewijzigd door BalusC op 03-11-2006 09:31 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dido schreef op vrijdag 03 november 2006 @ 09:25:
[...]

In je takenlijst wil je dan alleen een koppeling leggen tussen 1 naam en 1 taak!
Misschien is hier een misverstand, ik wil 1 taak linken aan verschillende namen vandaar dat ik takenlijst gebruik om de 2 overige tabellen te linken. Maar ja daar gaat dit topic op zich niet over maar wel handig om te weten voor de toekomst. Dus verdere comment is altijd welkom.
BalusC schreef op vrijdag 03 november 2006 @ 09:27:
[...]
99 kolommen voor 1 doel .. Dit kan veel beter in 2 kolommen :)
[...]
Met "dynamisch" bedoel ik dat je met PHP runtime een query samenstelt op basis van de eisen in plaats van om met de hand neer te tikken (statisch). En over array's is genoeg te vinden in de PHP tutorials en de uitstekende documentatie op php.net.
Dat is juist de reden waarom ik dit topic open want ik heb gezocht op php.net maar ik raak eerlijk gezegd niet wijzer uit hoe ik die arrays kan hanteren om dit probleem op te lossen. Indien iemand mij een aanzet kan geven is dat voldoende en zeer welkom. Want hoe kan ik een array gebruiken in het voorbeeld script van dit topic?

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

[google=array site:php.net] :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Sinds zaterdag ben ik al aan het zoeken naar een goede manier, dus kan er iemand aub meer info geven dan juist een link naar de site die ik al meerdere malen heb bezocht.

Want ik weet niet hoe ik die array kan gebruiken in het SQL script dat ik gebruik. Voor de meeste mensen die vertrouwd zijn met PHP en MYSQL is het misschien kinderspel maar voor mij helaas nog niet ;)

Daarom kan er iemand zeggen hoe ik die array kan verwerken in onderstaand script, alvast hartelijk bedankt:
--------------------
query = "SELECT * FROM Takenlijst Where ...ARRAY... ORDER BY ID"

$result = mysql_query($query);
---------------------

Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 12:47

Dido

heforshe

Verwijderd schreef op vrijdag 03 november 2006 @ 09:41:
Misschien is hier een misverstand, ik wil 1 taak linken aan verschillende namen vandaar dat ik takenlijst gebruik om de 2 overige tabellen te linken. Maar ja daar gaat dit topic op zich niet over maar wel handig om te weten voor de toekomst. Dus verdere comment is altijd welkom.
Dat is precies wat ik beschrijf :)

Je hebt een taak:

Taakid=1, en een zooi andere gegevens in tabel Taak

Je hebt 5 personen:
PersoonID=1, 2, 3, 4 en 5, en andere gegevens in tabel Persoon (of Naam, wat een vage tabelnaam is).

Dan ga je koppelen in tabel TaakPersoon (Takenlijst is een verwarrende naam!), er hoeft in die tabel niets anders dan dit:

code:
1
2
3
4
5
6
TaakID PersoonID
   1      1
   1      2
   1      3
   1      4
   1      5

Nu heb je vijf personen gekoppeld aan taak 1, als je wilt zoeken op naam, bijnaam, of whatever je in de tabel Persoon opslaat over je mensen, kan dat met iets als dit:
code:
1
2
3
4
5
SELECT T.*
  FROM Taak T
  JOIN TaakPersoon TP on T.ID = TP.TaakID
  JOIN Persoon P on P.ID = TP.PersoonID
 WHERE P.Bijnaam = 'Jan';

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Verwijderd schreef op vrijdag 03 november 2006 @ 09:41:
[...]


Misschien is hier een misverstand, ik wil 1 taak linken aan verschillende namen vandaar dat ik takenlijst gebruik om de 2 overige tabellen te linken. Maar ja daar gaat dit topic op zich niet over maar wel handig om te weten voor de toekomst. Dus verdere comment is altijd welkom.
De tabel Takenlijst is dus een koppeltabel die de tabel Namen met Taken koppelt.
Takenlijst hoeft dus maar twee kolommen te bevatten (is dit al het geval?): een kolom om de ID van een taak (uit Taken) op te slaan en een ID van een naam. Stel dat je twee namen aan een taak koppelt, dan sla je twee rijen in de tabel takenlijst op waarbij de id_taak gelijk is.

Wil je nu alle namen die aan een taak (in dit geval met ID 1) zijn gekoppeld weten, gebruik dan een query zoals:
SQL:
1
2
3
4
SELECT namen.*
  FROM namen, taken, takenlijst
 WHERE taken.id = '1' AND
       namen.id = takenlijst.id_naam

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor de tips maar de tabel is zo opgezet dat er meerder namen gelinkd zijn met 1 taak in 1 rij. Aangezien de ID van de taken uniek moet zijn om conflicten te voorkomen.

Acties:
  • 0 Henk 'm!

  • lammert
  • Registratie: Maart 2004
  • Laatst online: 03-09 11:50
Ga je alsjeblieft verdiepen in normalisatie van je database. Klinkt misschien moeilijk als je er niet mee bekend bent maar is echt vrij simpel te leren en gaat je ZO VEEL werk besparen. Als je op deze manier begint raak je alleen maar steeds verder in de knoop. Google eens op "database normaliseren": hier nog een directe link naar een goed, simpel voorbeeld op Webessence

Het verbaast mij overigens dat het woord normalisatie nog niet gevallen is in dit draadje...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Kan er iemand mij vertellen waar ik ad hoc info can vinden om in een SQL script arrays te gebruiken want ik geraak er hier niet wijzer uit.

De structuur is zoals hij is, en zal wss in de toekomst wel aangepast worden. (op die manier zal ik het ooit wel leren ;))

Dus graag info over hoe ik in het eerder getoonde SQL script gebruik kan maken van een dynamisch script zoals arrays of dergelijke.

Alvast bedankt

Acties:
  • 0 Henk 'm!

  • lammert
  • Registratie: Maart 2004
  • Laatst online: 03-09 11:50
Meneer is eigenwijs >:)

Besef je goed dat als je de databasestructuur LATER aanpast dat je dan ook AL je php scripts en SQL queries moet aanpassen!

Maar goed, je kan t hebben zoals je t wil: maak een for loopje in php waarin je de SQL query 99 keer laat herhalen (bijnaam$i='jan'). Zoiets misschien:
PHP:
1
2
3
4
for(i=1;i<100;i++){
 $sql="SELECT * FROM takenlijst WHERE bijnaam$i='jan' ORDER BY id";
 $result = mysql_query($sql);
}


Maar het is ZO FOUT... Ik garandeer je dat het je op jouw manier meer tijd, moeite en frustratie gaat kosten dan een simpele normalisatie van je database en dan een query toepassen met een LEFTJOIN of INNERJOIN op 2 tabellen. Lees ajb de link die ik hierboven postte... normalisatie is niet eng.

edit:
code toegevoegd, ben in een goede bui, is niet getest overigens

[ Voor 17% gewijzigd door lammert op 03-11-2006 12:56 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
het gaat hier niet om eigenwijs te zijn maar ik wil gewoon iets hebben dat werkt tegen zondag. In een latere fase moet ik toch alles opnieuw doen. Want ik heb namelijk reeds een hele reeks sql script gebasseerd op deze structuur. Het is een kwestie van tijdsdruk/leerprocess.

Toch bedankt voor al jullie de tips.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Dit is absoluut geen kwestie van leerproces. Voor zondag heb je nog anderhalve dag. Ik kan je nu al op een presenteerblaadje aangeven dat de (kompleet normale, en standaard door iedereen in deze situatie gebruikte) koppeltabel je misschien vandaag nog meer werk gaat opleveren, maar morgen zul je er alleen maar voordelen van hebben.

Databases is een vakgebied dat al 40 jaar oud is. 40 jaar lang denken er al vele mensen na over wat nu de meest handige techniek is om bepaalde dingen te doen. 20 jaar terug was iedereen het er al over eens dat een koppel tabel de manier was om een meer op meer relatie aan te geven. Als jij vervolgens met je twee weken (gokje) ervaring het op een andere manier wilt doen dan kan ik gewoon niet anders zeggen dan dat je eigenwijs bent..

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1