» »

Malce zahtevnejši SQL stavek včasih narobe SELECT-a

Malce zahtevnejši SQL stavek včasih narobe SELECT-a

Brilko ::

Zdravo!

Mam en problem, ki me kr lepo zajebava. In sicer, imam tabelo novice(id, naslov, datum...), kjer je vpisana novica in novice_slike (id, id_slike, slika), kjer so vpisane slike konkretne novice. Zdej mam pa spodnji SQL stavek, ki naj bi prebral vse novice in za vsako novico izbral še po eno sliko iz tabele novice_slike (seveda za pripadajočo novico), ampak to prvo, ki je bila dodana (torej najmanjši ID). Spodnji SQL stavek za 95% primerov dela, ampak včasih se mu pa zmeša.

SELECT novice.*,novice_slike.slika,COUNT(novice_slike.id) AS stevilo FROM novice LEFT JOIN novice_slike ON novice.id = novice_slike.id_novice GROUP BY novice.id ORDER BY novice.id DESC

Ma kdo kako idejo zakaj, oz. kaj dodati, da bo delalo prav?

Hvala in LP!

Jst ::

Am... enkrat sem delal na enem cudnem cudnem sql serverju, kjer sem imel isti problem, ki ga imas ti. Kaj sem moral narediti? Fakin subselect v where stavku, ker ni sprejel (Where Id = MAX(ID)).

Poldi112 ::

Na kakšen način se mu zmeša in kje v tvojem stavku si mu podal naj vzame zadnjo sliko?
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

Brilko ::

Poldi112, ja, drugo vprašanje, res nisem konkretno dodal, ampak mislim da naj bi že sam tako uredil (ker vedno delam tako, sam tuki sem vidu da zelo redko ga zjebe). Čeprav sam trenutno nevem kako.

V teoriji bi mislo, da bi dau še en ORDER BY za novice_slike.id znotri JOIN-a, sam sintaksa stavka tega ne sprejme... Če veš kako bi prosil!

Jst, server je OK, ker sem tud na mojga prenesu celo bazo in sem ugotvil da na isti način SELECT-a k na kterem stvar teče. Res pa je da to ne vzame kar si dau primer... :O

Zgodovina sprememb…

  • spremenil: Brilko ()

ADF ::

Najbrž bi moral uporabiti min(novice_slike.id) in ne count funkcijo, saj te ne zanima koliko slik je, pač pa katera je najmanjša.

Sicer pa je ta tvoj SQL malce čuden:

Za enačajem imaš kvalifikator "novice_slike.id_novice" , medtem ko si zgoraj tabelo opisal kot "novice_slike (id, id_slike, slika)". Od kod potem "id_novice" stolpec mi ni jasno.

Brilko ::

Se opravičujem, narobe sem napis pod strukturo tabele, itak da je id_novice.

COUNT naj te ne skrbi, je zato notri, da prešteje koliko slikc je pri novici. MIN pa sem tudi še dodatno probal uporabiti, vendar ni delalo...

BigWhale ::

select novice.* MIN(novice_slike.slika), ... FROM novice, novice_slike WHERE novice.id = novice_slike.id_novice

Mogoce namesto MIN() uporabis na koncu kak order by in potem izberes samo prvi result, ki ti ga vrne ali pa kaksna podobna zadeva.

Zgodovina sprememb…

  • spremenil: BigWhale ()

Microsoft ::

Ker nisem vesc s temle bi se tule postavil podvrpasanje. Kaj naredi tole:
GROUP BY novice.id

Namrec, predstavljal bi si, da je id stolpec PK. Ce potem grupiras po unique vrednostih, ja nisi s tem nic naredil?:\


by Miha
s8eqaWrumatu*h-+r5wre3$ev_pheNeyut#VUbraS@e2$u5ESwE67&uhukuCh3pr

Zgodovina sprememb…

Brilko ::

Microsoft: s tem ko JOIN-aš tabele, se ti naredi toliko rezultatov, kot je slik, zato GROUP-iraš. Je jasno?

Nekaj razmišljam glede rešitve... :\

Zgodovina sprememb…

  • spremenil: Brilko ()

Brilko ::

Ne, v nobenem primeru mi ne uspe priti do rešitev... ;((

8-O

Brilko ::

Če bi me to zadovoljilo, pol nebi več spraševal.

Preprosto, ne najdem! Glavna fora ki se mi poraja je. Preden gropira ima tako imenovani kartezični produkt, izpise more imeti nekako urejene, potem pa še grupira, in verjetno prvi zapis ohrani, ostale pa ne (pri grupiranju), tako da bi mogel pravi vrstni red vzeti... to je tisto primerno razmišljanje o delovanju.... sam kak mu zdej konkretno definirati vrstni red pred grupiranjem.

Sam sem brez idej! ;((

Poldi112 ::

Gotovo obstaja tudi boljši način...

select novice.*,(select slika from novice_slike where novice.id=novice_slike.novica_id order by id desc limit 1) as slika order by novice.id desc;

On nič ne ureja, če mu ti ne rečeš. Tako kot jih najde tako ti jih prikaže. Najde jih pa bolj na random (odvisno od tega kako išče - iskati se pa trudi tako da čim hitreje najde).
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

Zgodovina sprememb…

  • spremenil: Poldi112 ()

Microsoft ::

Jst sem se zdele s tem nekaj igral in preizkusal. Naredil sem dve tabeli; TabelaA in TabelaB. TabelaA ima na stolpcu id PK, od TabelaB tabele ida pa je vezan na ta PK. Potem pa sem naredil tko, da pac zbere samo eno sliko. Pa mislim, da dela.:\




by Miha
s8eqaWrumatu*h-+r5wre3$ev_pheNeyut#VUbraS@e2$u5ESwE67&uhukuCh3pr

Zgodovina sprememb…

Brilko ::

Ja, hvala za trud Microsoft. Poldi, to sem že napisal ti da subquery ni tuki tisto, kar bi me rešilo.

Ja, ugotovil sem, da pač vzame prvega iz tistega kartezičnega produkta, urejanost tega kartezičnega pa je drug problem, in tudi sam vidim, da je zelo čudno razmetano pri meni (zakaj še morem ugotoviti). Microsoft, saj dela ql v večini, ampak ene par zapisov pa je pomešanih, kar zmeša zadevo, tebi pa lepo dela (ker so normalno vnosi, saj pri meni so tudi, ampak nekaj pa je zmešanih, nevem zakaj)... Hm... morem še poštudirita zakaj so nekje zapisi zamešani nekje v sredini.


Ker načelom SELECT brez kakršnegakoli pogoja izpiše glede na vnosa (vrstni red) ane (torej po id-u, ki je aoutincrement), ampak pri meni so zapisi nekej malo zamešani.

CWIZO ::

Baza ti zapise vrne popolnom random.
Dokler nic ne brises ter updejtas ti jih sicer vraca v vrstnem redu vnosa, ko pa kaj zbrises in nkeja novega vneses se pa zadeve zacnejo pomesane vracat...
hancic.info
I can't uninstall it, there seems to be some kind of "Uninstall Shield"...

Brilko ::

Ja... sem preveril in to je res. Torej to pomeni da pred GROUP da ta naključni vrsti red in da se lahka jebem da bom vrstni red spremenil? 8-O

Poldi112 ::

Moj query z subquery-jem naredi točno to kar ti hočeš. Imaš kak konkreten razlog da ti subquery ni všeč?
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

Brilko ::

Ja vem, sej če bi hot s subquerijem bi že prej to naredu, sam kaj ko je potrošnja querijev...

Sem pa sedaj vrstni red uredil tako, da sem najprej pod ORDER uredi glede na ID pa nato vpisal nazaj vse zapise po vrstnem redu, je pa to samo začasna rešitev pred novimi vpisi (sej načeloma niso zelo pogosto, ampak vseeno).

Tak da začasno sem uredil, ampakme pa zanima rešitev z enim querijem, da bi si urdeil še vrstni red. LP.

WarpedGone ::

Potrošnja querrijev? Če te skrbi optimalnost izvajanja pol raj glej dejanske parametre izvajanja ne pa kr od oka štet kolk selectov maš u eni poizvedbi in se jim izogibat ker se ti pač tko zdi. V tvojem primeru je edina legalna in 'lepa' pot uporaba takih al pa drugačnih subquerrijev, to kar si naredu je 'dirty hack', dela slučajno dokler ne boš na to pozabu, čez poleta se bo pa cela firma praskala po glavi kakšne čudne reči se nenadoma dogajajo. Vrstni red zapisov v tabeli NI DOLOČEN, je RANDOM. To da občasno letijo vn u enakem vrstnem redu kot so šli noter je SLUČAJ. Zanašanje na slučaj je pa hudo nespametno početje. Če hočeš met določen vrstni red, ga morš zahtevat - ORDER BY. Na nivoju enga querrija lahk sortiraš sam enkrat -in to na koncu, ko so vse ostale operacije in pod-operacije že izvedene (subquerriji).

V akademske namene:

Subselectu se legalno losaš, če recimo v tabeli novice_slike, id_slike določuješ relativno glede na id novice in maš sestavljen PK. Torej za vsako novico posebej začneš slike številčit recimo z 1. Tako veš, da je najmanjši id_slike (kadar sploh obstaja) enak 1 in lahk nardiš lepo outerjoin med novicami in slikami. Če se še mal nerealno omejiš in zahtevaš za vsako novico vsaj eno sliko, zadevo sfuraš tut s full joinom.
Zbogom in hvala za vse ribe

WarpedGone ::

Da bo jasno: v outer ali full joinu se seveda omejiš po id_slike = 1.
Zbogom in hvala za vse ribe

Brilko ::

WarpedOne, dobra ideja!

In pa da je v tem primeru ključ sestavljen (id,id_novice).

Stem, da potem, če hočeš jih prešteti, rabiš še vedno nov query. :\

WarpedGone ::

Ti bi rad naenkrat dobil število slik za novico in še eno random (recimo prvo) sliko? Z enim samim selectom brez subquerrijev? No can do.

Edit: razn sevda če si v tabeli novice ne zmisliš dodatenga stolpca, recimo stevilo_slik, kjer hraniš trenutno število slik za dano novico. Ob vsakem insertu/deletu slike ta števec ustrezno popraviš. Tko boš pol lahk dosegu ta svoj sveti gral enga samga simpl selecta, ki ti hkrati vrne število vseh slik in eno vzorčno.
Zbogom in hvala za vse ribe

Zgodovina sprememb…

mn ::

Ne bo slo z zvezdico vendar ce izpises vse stolpce iz tabele novice in grupiras po vseh stolpcih iz tabele novice dobis tocno kar zelis. Ker ne poznam stolpcev v tabeli novice sem uporabil stolpec1, stolpec2, stolpec_n. Ce sem te prav razumel spodnji select vrne tocno to kar zelis.

select novice.stolpec1, novice.stolpec2, novice.stolpec_n, MIN(novice_slike.slika), COUNT(novice_slike.slika)
FROM novice, novice_slike
WHERE novice.id = novice_slike.id_novice
GROUP BY novice.stolpec1, novice.stolpec2, novice.stolpec_n

Povej ce dela.

WarpedGone ::

MIN nad slikovnim poljem? Tole me pa res zanima, kaj nardi :)
Zbogom in hvala za vse ribe

mn ::

>> MIN nad slikovnim poljem? Tole me pa res zanima, kaj nardi :)

No ja. Nikjer ni napisal, da je to slikovno polje. V tem primeru se bo pac treba drugace znajti.

Brilko ::

mn: ja sej id najmanjšega ni problem dobit, fora je v tem, ker za pot do slike (novice_slike.slika) bo pa še vedno tam ven vzeta iz prvega od "naključnih".

Zgodovina sprememb…

  • spremenil: Brilko ()

BigWhale ::

Eh, daj, stvar je trivialna. mn pa ima verjetno prav, da z novice.* ne bo slo.

Tole sem sedaj zasimuliral:

SELECT novica.id AS n_id, slika.id AS s_id, slika.id_n AS n_s_id, COUNT(slika.id) AS cnt FROM novica,slika WHERE slika.id_n=novica.id GROUP BY novica.id;

V tabeli novica imam stiri vrstice z id-ji od 1 do 4, v tabeli slike imam sedem vnosov z id-ji od 1 do 7 in potem random nametane se relacije slik na novice. S tem, da do cetrte zadnje novice ni nobene povezane slike.

Zgornji select mi vedno vrze ven tri novice, s pripadajocimi IDji slik. Vedno dobim ven prve tri slike. Pa tudi za vsako novico je stevilo slik pravilno.

BigWhale ::

Aja, tole so tabele, ki sem jih ponucal:
mysql> desc novica;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  |     | NULL    |       |
| text  | varchar(244) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> desc slika;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  |     | NULL    |       |
| id_n  | int(11)      | YES  |     | NULL    |       |
| text  | varchar(233) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

Zgodovina sprememb…

  • spremenil: BigWhale ()

BigWhale ::

Rezultat:
+------+------+--------+-----+
| n_id | s_id | n_s_id | cnt |
+------+------+--------+-----+
|    1 |    2 |      1 |   4 |
|    2 |    1 |      2 |   2 |
|    3 |    4 |      3 |   1 |
+------+------+--------+-----+
3 rows in set (0.00 sec)

BigWhale ::

Ce hoces, ti se vsebino tabel sem not zalimam... Nevem, ali jaz nisem razumel kaj ti hoces ali pa vsi skupaj precej prevec komplicirate. Res prevec.

Ali pa je MySQL tako leet, da mi kar vse sam naredi tako kot jaz hocem. ;)

Brilko ::

Lej, nisi prebral cele teme... saj to deluje, če bi bli zapisi v pravilnem vrstne redu in v 90% dela, ampak kot smo ugotovili, kjer se je urejalo in malo brisalo, se je pa vrstni red, ki ga baza izpljune brez pogoje malce spremeniu, probaj ti zamenjati vpsie v novice_slike.

Primer, če imaš zapise:
5 6 nek_tekst
4 6 drug_tekst

Kar je moj cilj je, da ti izpiše drug tekst, ker ma nižji id, torej prva dodana, izpisalo ti bo pa nek_tekst ker je po nekem brezveznem naključju brez pogoja prej!

Verjetno zdaj veš poanto.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[SQL] teževa pri iskanju zapisov

Oddelek: Programiranje
101977 (1567) lopow
»

PHP pridobivanje podatkov iz dveh tabel po tujem ključu

Oddelek: Izdelava spletišč
141074 (842) SkIDiver
»

[SQL] PgAdmin preprosto vprasanje povezano s stolpci v tabeli

Oddelek: Programiranje
222098 (1457) Cvele2011
»

mySQL(+php) auto_increment field v tabeli.. Kako...?

Oddelek: Izdelava spletišč
61041 (973) Zzzzzzz
»

En enostaven querry v MySQL :(

Oddelek: Programiranje
141395 (1196) krneki0001

Več podobnih tem