mysql avtomatsko štetje

matejdro

HACKER 08
6. jan 2008
2.267
0
36
Recimo, da imam tako tabelo v mysql:
+----+---------+
| id | ime |
+----+---------+
| 1 | alter1 |
| 2 | alter2 |
| 3 | alter3 |
+----+---------+

in če bi sedaj alter1 izbrisal, bi alter2 avtomatsko dobil id 1. Se da to?
 

Utisevalec

Guru
12. nov 2007
16.156
4.132
113
Kako je pa z indexi?

Če je (kar bi bilo edino prav) ID primarni ključ, potem ne moreš/smeš spreminjat IDjev, ker s tem rušiš indeksno strukturo.

Če rabiš zaporedne številke iz SELECT stavka, potem uporabi drugo metodo. Npr.

set @zaporedna = 0;
SELECT *, @zaporedna := (@zaporedna + 1) as zaporedna_id FROM tabela
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.878
698
113
Zakaj pa bi sploh potreboval to ? Ker v večini primerov spreminjanje IDjev ni priporočljivo.

Sicer pa je zelo enostavno

1. stavek
Koda:
 DELETE FROM tabela WHERE id = x;

2. stavek
Koda:
 UPDATE tabela SET id = id - 1 WHERE id > x;

2. stavek lahko izvedeš tudi kot trigger (torej boš samo izbrisal, IDji pa se bodo sami popravili).
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
rabim nekaj takega, kot drugi stavek, vendar je problem če recimo izbrišem alter1 in alter2. Potem dobi alter3 2 namesto 1.

Je pa v tej tabeli še veliko drugih vnosov, id pa je v resnici order, primarni ključ je drugje, tako da spreminjanje ni problem.
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.878
698
113
Citat:
Uporabnik matejdro pravi:
rabim nekaj takega, kot drugi stavek, vendar je problem če recimo izbrišem alter1 in alter2. Potem dobi alter3 2 namesto 1.

Drugi stavek (če je izveden kot trigger) dela točno to kar rabiš. Torej ko izbrišeš alter1, boš imel

+----+---------+
| id | ime |
+----+---------+
| 1 | alter2 |
| 2 | alter3 |
+----+---------+

Ko pa izbrišeš še alter2, pa ti ostane

+----+---------+
| id | ime |
+----+---------+
| 1 | alter3 |
+----+---------+

To pa zato, ker se id zmanjša vsem, ki imajo večjega od tega ko brišeš. Zato se alter3 2x zmanjša in potem dobiš na koncu 1.
Ampak to deluje le, če imaš že v štartu vse IDje brez lukenj (drugače se ti bodo ohranjale).
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
1. Kako izvedem kot trigger?
redface-1.gif

2. Kaj pa če imam že v štartu nekje med idji luknje?

EDIT: 3. WTF je tu narobe? Navicat mi javi syntax error
Koda:
UPDATE merchant_buylists SET order = order - 33 WHERE shop_id = 5000;
(sem jih že prej 33 izbrisal).
 
Nazadnje urejeno:

Mikrohard

iPhone Profi
20. jul 2007
5.884
764
113
www.jernej.org
Trigger je simpl... za tvoj primer tako:
CREATE TRIGGER popravi_id
AFTER DELETE ON tabela
FOR EACH ROW BEGIN
UPDATE tabela SET id = (id - 1) WHERE id > OLD.id;
END;

Pri tvoji sintaksi daj pa order - 33 v oklepaj in poročaj...
UPDATE merchant_buylists SET order = (order - 33) WHERE shop_id = 5000;
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.878
698
113
Citat:
Uporabnik matejdro pravi:
EDIT: 3. WTF je tu narobe? Navicat mi javi syntax error
Koda:
UPDATE merchant_buylists SET order = order - 33 WHERE shop_id = 5000;
(sem jih že prej 33 izbrisal).

Glede syntax errorja zdaj na pamet ne bi vedel, ampak možno da res manjkajo oklepaji.
Pa če si jih 33 že izbrisal (upam da so bili skupaj v gruči), potem moraš tam dati WHERE shop_id > 5000, kjer je 5000 ID eden izmed 33 izbrisanih. S tem boš vsem nadaljnjim znižal ID za 33 in bodo spet lepo skupaj.
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
shop_id je nekakšna kategorija, order pa so številke, ki bi jih rad razvrstil. Pod 34 ni nobenega vnosa, tako da order < 33 ne pomeni nič.
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.878
698
113
Aja, sem spregledal ime polja. Sem mislil da hočeš ravno shop_id zmanjšati vsem
grin1.gif

Trigger ti že deluje ?

Sicer pa zakaj točno ne bi rad imel lukenj vmes ? Ker sortiranje po tem polju bo delalo tudi z njimi.
 

Utisevalec

Guru
12. nov 2007
16.156
4.132
113
A nebi povedal bistvo problema in kaj pravzaprav želiš doseči?
evil.gif


Podatkovne baze so zato da se z njimi dela mnogo in še več, samo prav morajo biti sestavljene. Če moraš ob vsakem izbrisu nekega vnosa popravljat vnose vseh ostalih, je napaka že v sami strukturi tabele ali pa napačni uporabi samih zmožnosti baze.
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
Vbistvu je tale tabela nek seznam, shop_id pove kategorijo, vsaka kategorija pa ima svoj order. Order pa pač pove, kje točno na seznamu mora biti vnos. Sicer pa mislim, da je ta SET x=x-33 rešitev, le da še morem pogruntat zakaj mi ga ne sprejme.
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
mislim da sem tudi odkril, zakaj javi syntax error. Očitno je order tudi neka komanda ali kaj od mysql, ker če spremenim order v karkoli drugega, mi sprejme. Problem pa je v tem,da programa, ki te podatke uporablja ne morem spreminjati. Any ideas?

EDIT: ok mi je ratalo. Order sem spremenil v order2, zagnal in spremenil nazaj. Case solved
smile-1.gif
 

Utisevalec

Guru
12. nov 2007
16.156
4.132
113
Citat:
Uporabnik matejdro pravi:
mislim da sem tudi odkril, zakaj javi syntax error. Očitno je order tudi neka komanda ali kaj od mysql, ker če spremenim order v karkoli drugega, mi sprejme. Problem pa je v tem,da programa, ki te podatke uporablja ne morem spreminjati. Any ideas?

EDIT: ok mi je ratalo. Order sem spremenil v order2, zagnal in spremenil nazaj. Case solved
smile-1.gif

Ja mogoče bi ORDER BY v SELECT stavku pomagal rešiti tudi tvoj problem izpisa nekega seznama sortiranega po neki vrednosti!
evil.gif


Skratka če ima vsak vnos samo eno kategorijo in je order vrstni red tega vnosa, potem lahko uporabiš stavek ...

SELECT * FROM tabela WHERE kategorija = X ORDER BY `order`

tako ti ni treba popravljati vrednosti, ker "order by" razvrsti seznam od najnižje vrednosti do najvišje. ČE hočeš obratno imaš še dodatek DESC (ORDER BY `order` DESC).

Drugače pa lahko uporabiš enojni narekovaj (un ta poševni -> `) za polje, tako da ti ga nedvoumno poveže s poljem in ne z ukazom.
 

matejdro

HACKER 08
6. jan 2008
2.267
0
36
saj sem že povedal, da programa, ki bere ne morem spreminjati. Če bi ga lahko teme sploh ne bi naredil
smile-1.gif