[SQL] positie 1 lager
ik heb een tabel
(id int(11),position int(11),img varchar(255),name varchar(255))
ik wil een rij ertussen verwijderen, dus moeten alle rijen waarvan de positie hoger is dan de rij die verwijderd wordt, met 1 worden verlaagd. Van de rij die verwijderd wordt heb ik de id. Nu wil ik met 1 query de rijen ophogen, zonder eerst de positie v/d rij op te halen, dus ik dacht aan iets zoals:
UPDATE celp_software_os SET position=position-1 WHERE position>(SELECT position FROM celp_software_os WHERE id=8)
Het lijkt mij dat het klopt op het SELECT deel na, wat moet daar komen te staan?
(id int(11),position int(11),img varchar(255),name varchar(255))
ik wil een rij ertussen verwijderen, dus moeten alle rijen waarvan de positie hoger is dan de rij die verwijderd wordt, met 1 worden verlaagd. Van de rij die verwijderd wordt heb ik de id. Nu wil ik met 1 query de rijen ophogen, zonder eerst de positie v/d rij op te halen, dus ik dacht aan iets zoals:
UPDATE celp_software_os SET position=position-1 WHERE position>(SELECT position FROM celp_software_os WHERE id=8)
Het lijkt mij dat het klopt op het SELECT deel na, wat moet daar komen te staan?
Quote:
ik wil een rij ertussen verwijderen, dus moeten alle rijen waarvan de positie hoger is dan de rij die verwijderd wordt, met 1 worden verlaagd
Dat snap ik niet.
Voorbeeldje:
1
2
3
En nu verwijder ik de waarde 2 en hou ik dus over:
1
3
Dit is dus exact dezelfde volgorde als voorheen, alleen mist er nu 1 record. So what?
Een integer kan een paar miljard waardes bevatten, de kans dat dit een probleem wordt, is bijzonder klein. En mocht het een probleem worden, verkoop je jouw product voor heel veel geld of converteer je de INT naar een BIGINT.
het gaat erom dat de id's een grote wirwar mogen zijn (daarvoor zijn het id's), maar de positie id's moeten aansluitend zijn, zo kun je de volgorde op de website (van bijv. menu items) bepalen.
vb:
id | position |
1 | 1
2 | 3
5 | 2
7 | 5
8 | 4
nu verwijder ik een rij (id=5).
dan wil ik dat dat de positie van 3 rijen met 1 wordt verlaagd (id=2,7,8)
zodat het word:
id | position |
1 | 1
2 | 2
7 | 4
8 | 3
vb:
id | position |
1 | 1
2 | 3
5 | 2
7 | 5
8 | 4
nu verwijder ik een rij (id=5).
dan wil ik dat dat de positie van 3 rijen met 1 wordt verlaagd (id=2,7,8)
zodat het word:
id | position |
1 | 1
2 | 2
7 | 4
8 | 3
Is niet nodig, je moet niet denken in de nummers maar in de prioriteit van deze nummers. Nr. 1 komt altijd als eerste, nr. 2 komt altijd voor nr. 3,4,5,6,7, etc. maar ná nr. 1, mocht deze aanwezig zijn. Het doet dus helemaal niet ter zake of 1 nu wel of niet aanwezig is, de volgorde blijft hetzelfde. De waarde "2" kan afhankelijk van de andere waardes en de gewenste sortering (ASC, DESC of random) een bepaalde positie krijgen. Het enige dat je met de kolom position wilt doen, is een relatieve positie geven ten opzichte van de andere waardes in deze kolom. In de browser kun je iedere vorm van presentatie kiezen, dat staat helemaal los van de onderlinge posities.
Je probeert een probleem op te lossen die er helemaal niet is.
Je probeert een probleem op te lossen die er helemaal niet is.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
ik snap best dat er manieren zijn om dit veel beter te doen en slimmer aan te pakken. (Ik zie wel dingen van deze methode terug in SGP, een portaal van phpbb3).
Mijn vraag was, wat de juiste sql-code om mijn 'onhandige' plan te bereiken..
Ik waardeer je commentaar, maar voor ingewikkeldere volgorde veranderingen is het voor mij handiger als de 'relatieve' nummers aansluitend zijn.
Mijn vraag was, wat de juiste sql-code om mijn 'onhandige' plan te bereiken..
Ik waardeer je commentaar, maar voor ingewikkeldere volgorde veranderingen is het voor mij handiger als de 'relatieve' nummers aansluitend zijn.
Tja, wat jij wil:
Let er heel goed op dat dit fout gaat wanneer je meerdere records in 1x verwijdert en dat je altijd een update uitvoert nadat je een delete hebt gedaan. De update kun je automatiseren met een trigger, het beperken van de delete tot slechts 1 record, kun je niet afdwingen. De trigger zal dan ook de mist in gaan. En dus ga je hier bewust risico's nemen zonder dat er enige winst tegenover staat.
En een corrupte database is niet handig.
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
DELETE FROM tabelnaam WHERE positie = 3;
UPDATE
tabelnaam
SET
positie = positie -1
WHERE
positie > 3;
UPDATE
tabelnaam
SET
positie = positie -1
WHERE
positie > 3;
Let er heel goed op dat dit fout gaat wanneer je meerdere records in 1x verwijdert en dat je altijd een update uitvoert nadat je een delete hebt gedaan. De update kun je automatiseren met een trigger, het beperken van de delete tot slechts 1 record, kun je niet afdwingen. De trigger zal dan ook de mist in gaan. En dus ga je hier bewust risico's nemen zonder dat er enige winst tegenover staat.
Quote:
Denk even out of the box en verzin een betere oplossing. Je doet nu aannames (dat bepaalde getallen aanwezig zijn) en deze aannames gaan de mist in wanneer er meer dan 1 concurrent user op jouw database zit.maar voor ingewikkeldere volgorde veranderingen is het voor mij handiger als de 'relatieve' nummers aansluitend zijn.
En een corrupte database is niet handig.
nog 1 dingetje, ik heb alleen de id, niet de positie... dus eerst moet de positie aan de hand v/d id worden bepaald.
In PostgreSQL kun je de positie opvragen in de DELETE:
Deze query verwijdert het record met id 3 en geeft aan jouw applicatie de oude positie van dit record door. Het resultaat dus even fetchen en gebruiken als input voor de UPDATE.
Met MySQL (en andere databases) heb je een extra SELECT-query nodig die je voor de DELETE uitvoert.
Maar vergeet de trigger niet, die weet ook wat de positie is, zie OLD.positie.
Deze query verwijdert het record met id 3 en geeft aan jouw applicatie de oude positie van dit record door. Het resultaat dus even fetchen en gebruiken als input voor de UPDATE.
Met MySQL (en andere databases) heb je een extra SELECT-query nodig die je voor de DELETE uitvoert.
Maar vergeet de trigger niet, die weet ook wat de positie is, zie OLD.positie.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
bedankt voor je tips, ik zal er zeker rekening mee houden als er een positie systeem komt die door meer dan 1 gebruiker gebruikt zal worden. (Dit is voor het admin control panel)...
Tja, als je nu had uitgelegd wat het daadwerkelijke probleem is, dan hadden we dat kunnen oplossen. Dan hoef jij er nooit meer aan te denken dat je met meerdere users in de problemen kunt komen.
Gemiste kans.
Gemiste kans.
Wtf, hoe komt mijn reactie hier terecht?
Gewijzigd op 01/01/1970 01:00:00 door Roel -




