Autor Zpráva
FantomX1
Profil
Najprv by som chcel priblížiť o čo konkrétne ide. Chcem z databázy vybrať užívateľov podľa znamenia, ale stĺpec znamenie v databáze neexistuje, ten si sám vytvorím z mesiaca a dňa narodenia a potom podľa neho teda umelo vytvoreného stĺpca v pameti chcem vyberať užívateľov na základe toho akú možnosť (znamenie) vybrali v SELECT drop down menu. Ale vyhadzuje mi to chybovú hlášku.

SELECT DISTINCT nick,

CASE WHEN (RIGHT(datum_narodenia,5) >= '03-21') AND (RIGHT(datum_narodenia,5) <= '04-20') THEN 'baran'

WHEN (RIGHT(datum_narodenia,5) >= '04-21') AND (RIGHT(datum_narodenia,5) <= '05-21') THEN 'býk'

WHEN (RIGHT(datum_narodenia,5) >= '05-22') AND (RIGHT(datum_narodenia,5) <= '06-21') THEN 'blíženci'

WHEN (RIGHT(datum_narodenia,5) >= '06-22') AND (RIGHT(datum_narodenia,5) <= '07-22') THEN 'rak'

WHEN (RIGHT(datum_narodenia,5) >= '07-23') AND (RIGHT(datum_narodenia,5) <= '08-23') THEN 'lev'
WHEN (RIGHT(datum_narodenia,5) >= '08-24') AND (RIGHT(datum_narodenia,5) <= '09-23') THEN 'panna'

WHEN (RIGHT(datum_narodenia,5) >= '09-24') AND (RIGHT(datum_narodenia,5) <= '10-23') THEN 'váhy'

WHEN (RIGHT(datum_narodenia,5) >= '10-24') AND (RIGHT(datum_narodenia,5) <= '11-23') THEN 'škorpión'

WHEN (RIGHT(datum_narodenia,5) >= '11-23') AND (RIGHT(datum_narodenia,5) <= '12-21') THEN 'strelec'

WHEN (RIGHT(datum_narodenia,5) = '00-00') THEN 'neurčené'

WHEN ((RIGHT(datum_narodenia,5) >= '12-22') AND (RIGHT(datum_narodenia,5) <= '12-31')) OR ((RIGHT(datum_narodenia,5) >= '01-01') AND (RIGHT(datum_narodenia,5) <= '01-20')) THEN 'kozorožec'

WHEN (RIGHT(datum_narodenia,5) >= '01-21') AND (RIGHT(datum_narodenia,5) <= '02-19') THEN 'vodnár'

WHEN (RIGHT(datum_narodenia,5) >= '02-20') AND (RIGHT(datum_narodenia,5) <= '03-20') THEN 'ryby' END AS znamenie,

pohlavie, posledne_prihlasenie, uzivatelia.id AS uz_id FROM uzivatelia, pristupy WHERE 1 GROUP BY nick HAVING znamenie='ryby'

Toto je SQL príkaz, ktorý sa vykoná pri vyhľadávaní určitých užívateľov podľa znamenia na mojom chate.

Aby som vysvetlil o čo sa jedná, vlastne ide o to, že vyberiem z databázy nick užívateľa, slovíčko DISTINCT je tam preto, pretože keď spájam tabuľku peístupy s tabuľkou užívatelia neskor v SQL dotaze aby som nedostal mnohokrát ten istý nick v prípade že budem výhľadávať offline užívateľov, kedže jeden užívateľ (nick) môže mať offline prístupov mnoho.

Offline prístupy sú tie, ktoré majú už zaznamenané aj čas odhlásenia. Mám ich tam pre štatistiku príhlásení ako je počet prihlásení a doba prihlásenia.

Tabuľky nespájam pomocou JOIN, ale bežne pomocou WHERE, myslím že v tomto prípade tam nie je rozdiel, ide mi teraz o chybu.

Ešte to pre istotu zoskupím podľa nicku pomocou GROUP, aby mi fungovala klauzula HAVING na skupiny. Klauzula HAVING dokáže vyberat aj podla výrazov, kdežto WHERE len podľa presne zadaných hodnôt.

Lenže vyhodí mi to túto hlášku

" Unknown column 'znamenie' in 'having clause' "


Kdežto keď dám jednoduchý dotaz na databázu v PhpMyAdmin v tejto podobe


SELECT

CASE WHEN (RIGHT(datum_narodenia,5) >= '03-21') AND (RIGHT(datum_narodenia,5) <= '04-20') THEN 'baran'

WHEN (RIGHT(datum_narodenia,5) >= '04-21') AND (RIGHT(datum_narodenia,5) <= '05-21') THEN 'býk'

WHEN (RIGHT(datum_narodenia,5) >= '05-22') AND (RIGHT(datum_narodenia,5) <= '06-21') THEN 'blíženci'

WHEN (RIGHT(datum_narodenia,5) >= '06-22') AND (RIGHT(datum_narodenia,5) <= '07-22') THEN 'rak'

WHEN (RIGHT(datum_narodenia,5) >= '07-23') AND (RIGHT(datum_narodenia,5) <= '08-23') THEN 'lev'
WHEN (RIGHT(datum_narodenia,5) >= '08-24') AND (RIGHT(datum_narodenia,5) <= '09-23') THEN 'panna'

WHEN (RIGHT(datum_narodenia,5) >= '09-24') AND (RIGHT(datum_narodenia,5) <= '10-23') THEN 'váhy'

WHEN (RIGHT(datum_narodenia,5) >= '10-24') AND (RIGHT(datum_narodenia,5) <= '11-23') THEN 'škorpión'

WHEN (RIGHT(datum_narodenia,5) >= '11-23') AND (RIGHT(datum_narodenia,5) <= '12-21') THEN 'strelec'

WHEN (RIGHT(datum_narodenia,5) = '00-00') THEN 'neurčené'

WHEN ((RIGHT(datum_narodenia,5) >= '12-22') AND (RIGHT(datum_narodenia,5) <= '12-31')) OR ((RIGHT(datum_narodenia,5) >= '01-01') AND (RIGHT(datum_narodenia,5) <= '01-20')) THEN 'kozorožec'

WHEN (RIGHT(datum_narodenia,5) >= '01-21') AND (RIGHT(datum_narodenia,5) <= '02-19') THEN 'vodnár'

WHEN (RIGHT(datum_narodenia,5) >= '02-20') AND (RIGHT(datum_narodenia,5) <= '03-20') THEN 'ryby' END AS znamenie FROM uzivatelia HAVING znamenie='ryby' co mi vlastne vrati len niekolkokrát pod sebou bunky s hodnotami ryby podľa toho koľko je tam takých užívateľov, tak to ide.


Mohli by ste mi pomôcť nájsť chybu?

Celý skript aj s chybovou hláškou sa nachádza na www.xatchat.sk/uzivatelia.php no treba vybrať vyhľadávanie podľa znamenia a byť príhlásený. Vytvoril som účet pre odskúšanie na www.xatchat.sk. Nick je "SQL" a heslo je "heslo". Potom už len hore v menú stačí kliknúť na užívatelia a otvorí sa skript.

Vopred ďakujem za všetky rady a odpovede.

----------------
-FANTOMX1-
----------------
Leo
Profil
Osobne bych si v te tabulce sloupec znameni vytvoril. Leo
Kajman_
Profil *
Myslím, že nejrozumnější (vzhledem k rychlosti dotazů) by bylo vytvoření sloupečku s předpočítanými znameními jak píše Leo. Pak to bude jednoduché a rychlé.

Na stávajících sloupečcích bych to asi řešil jinak. Je třeba dát podmínku na znamení do where ne do having. Ale opravdu tam nejde použít 'znamení'... musí se tam dát ta podmínka na datum. V php bych si udělal pole podmínek, které bych dal do where části dotazu.

$vybrane_znameni='škorpión';
$znameni['škorpión']=" and ((RIGHT(datum_narodenia,5) >= '10-24') AND (RIGHT(datum_narodenia,5) <= '11-23'))";
...

$query="select .... where 1 ${znameni[$vybrane_znameni]}"
kaifman
Profil
presne tak udelal bych si jeste jednu tabulu

znameni (id int, text varchar(20), od date, do date);

a pri registraci bych do ni jukl kam pasuje datum narozeni a podle toho priradil id toho znameni
FantomX1
Profil
To Kajman: Ano, aj to ma napadlo, v PHP urobit podmienky pre znamenia, napríklad pomocou vetvenia switch a podľa toho vyberať ale zdalo sa mi to byť krajným riešením, chcel som to urobiť čiste pomocou SQL.

To Leo: Ano, aj tak sa to da spraviť, no chcel som ušetriť miesto, i keď tak to bude asi rýchlejšie.

To kaifman:

Ano, presne tak som o tom rozmýšlal predtým, v jednej tabuľke zoznam znamení a v druhej foreign key pre dané znamenie, to že kam patrí dané znamenie by už možno mohol zistiť aj samotný PHP skript.
vrbcik
Profil
Ahoj,

podľa mňa je ten dotaz napísaný z hľadiska DB strašne "prasácky" -
1. urobiť kartézsky súčin uzivatelia a všetky prístupy - si si istý, že to tak chceš?
Nemá tam byť JOIN uzivatelia a pristupy podľa mena užívateľa?
.
2. DISTINCT a GROUP BY robia to iste, jeden z nich je tam zbytočný....
3. znamenie nemá byť v GROUP BY tj. ani v HAVING, ale má byť vo WHERE (tj. keď do tabuľky UZIVATELIA pridáš stĺpec ZNAMENIE, budeš obmedzovať tabuľku pomocou WHERE).
4. Z hľadiska optimalizácie dotazu (pre veľke data, čo ty asi nemáš) je skutočne najlepšie pridat stĺpec ZNAMENIE do tabuľky, pre data do 5000 zaznamov (tabuľka do 60kB) to je jedno.
.
Ak ten prvý dotaz mal vyberať všetkých userov v znamení ryby a ich posledný prístup, napísl by som to takto:
.
SELECT uzivatelia.*, --ktore stlpce potrebujes
znamenie,
max(pristupy.datum_prihlasenia)
FROM UZIVATELIA JOIN PRISTUPY ON (uzivatel.id = pristup.uzivatel_id) --neviem tvoje stlpce
WHERE znamenie = 'ryby'
GROUP BY uzivatelia.* --vymenovane stlpce, ktore vyberas v select
vrbcik
Profil
Takže finálny select cca takto - snáď fungujú SUBSELECTy.... ak nie, tak je treba do WHERE podmienky dať celý CASE WHEN:

SELECT uzivatelia.nick, uzivatelia.znamenie, uzivatelia.pohlavie, uzivatelia.id,
max(pristupy.prihlasenie) posledne_prihlasenie
FROM (SELECT nick,
CASE WHEN (RIGHT(datum_narodenia,5) >= '03-21') AND (RIGHT(datum_narodenia,5) <= '04-20') THEN 'baran'
WHEN (RIGHT(datum_narodenia,5) >= '04-21') AND (RIGHT(datum_narodenia,5) <= '05-21') THEN 'býk'
WHEN (RIGHT(datum_narodenia,5) >= '05-22') AND (RIGHT(datum_narodenia,5) <= '06-21') THEN 'blíženci'
WHEN (RIGHT(datum_narodenia,5) >= '06-22') AND (RIGHT(datum_narodenia,5) <= '07-22') THEN 'rak'
WHEN (RIGHT(datum_narodenia,5) >= '07-23') AND (RIGHT(datum_narodenia,5) <= '08-23') THEN 'lev'
WHEN (RIGHT(datum_narodenia,5) >= '08-24') AND (RIGHT(datum_narodenia,5) <= '09-23') THEN 'panna'
WHEN (RIGHT(datum_narodenia,5) >= '09-24') AND (RIGHT(datum_narodenia,5) <= '10-23') THEN 'váhy'
WHEN (RIGHT(datum_narodenia,5) >= '10-24') AND (RIGHT(datum_narodenia,5) <= '11-23') THEN 'škorpión'
WHEN (RIGHT(datum_narodenia,5) >= '11-23') AND (RIGHT(datum_narodenia,5) <= '12-21') THEN 'strelec'
WHEN (RIGHT(datum_narodenia,5) = '00-00') THEN 'neurèené'
WHEN ((RIGHT(datum_narodenia,5) >= '12-22') AND (RIGHT(datum_narodenia,5) <= '12-31')) OR ((RIGHT(datum_narodenia,5) >= '01-01') AND (RIGHT(datum_narodenia,5) <= '01-20')) THEN 'kozorožec'
WHEN (RIGHT(datum_narodenia,5) >= '01-21') AND (RIGHT(datum_narodenia,5) <= '02-19') THEN 'vodnár'
WHEN (RIGHT(datum_narodenia,5) >= '02-20') AND (RIGHT(datum_narodenia,5) <= '03-20') THEN 'ryby' END AS znamenie,
pohlavie,
uzivatelia.id AS uz_id
FROM uzivatelia) uzivatelia
JOIN pristupy (uzivatelia.id=pristupy.uzivatel AND odhlasenie = 0)
WHERE uzivatelia.znamenie='ryby'
GROUP BY uzivatelia.nick, uzivatelia.znamenie, uzivatelia.pohlavie, uzivatelia.id
FantomX1
Profil
Tak toto som pouzil ako zjednodusenu formu

SELECT uzivatelia.nick, uzivatelia.znamenie
FROM (SELECT nick,
CASE WHEN (RIGHT(datum_narodenia,5) >= '03-21') AND (RIGHT(datum_narodenia,5) <= '04-20') THEN 'baran'
WHEN (RIGHT(datum_narodenia,5) >= '04-21') AND (RIGHT(datum_narodenia,5) <= '05-21') THEN 'býk'
WHEN (RIGHT(datum_narodenia,5) >= '05-22') AND (RIGHT(datum_narodenia,5) <= '06-21') THEN 'blíženci'
WHEN (RIGHT(datum_narodenia,5) >= '06-22') AND (RIGHT(datum_narodenia,5) <= '07-22') THEN 'rak'
WHEN (RIGHT(datum_narodenia,5) >= '07-23') AND (RIGHT(datum_narodenia,5) <= '08-23') THEN 'lev'
WHEN (RIGHT(datum_narodenia,5) >= '08-24') AND (RIGHT(datum_narodenia,5) <= '09-23') THEN 'panna'
WHEN (RIGHT(datum_narodenia,5) >= '09-24') AND (RIGHT(datum_narodenia,5) <= '10-23') THEN 'váhy'
WHEN (RIGHT(datum_narodenia,5) >= '10-24') AND (RIGHT(datum_narodenia,5) <= '11-23') THEN 'škorpión'
WHEN (RIGHT(datum_narodenia,5) >= '11-23') AND (RIGHT(datum_narodenia,5) <= '12-21') THEN 'strelec'
WHEN (RIGHT(datum_narodenia,5) = '00-00') THEN 'neureené'
WHEN ((RIGHT(datum_narodenia,5) >= '12-22') AND (RIGHT(datum_narodenia,5) <= '12-31')) OR ((RIGHT(datum_narodenia,5) >= '01-01') AND (RIGHT(datum_narodenia,5) <= '01-20')) THEN 'kozorožec'
WHEN (RIGHT(datum_narodenia,5) >= '01-21') AND (RIGHT(datum_narodenia,5) <= '02-19') THEN 'vodnár'
WHEN (RIGHT(datum_narodenia,5) >= '02-20') AND (RIGHT(datum_narodenia,5) <= '03-20') THEN 'ryby' END AS znamenie,
uzivatelia.id AS uz_id
FROM uzivatelia) AS uzivatelia
JOIN pristupy (uzivatelia.uz_id=pristupy.uzivatel AND odhlasenie = 0)
WHERE uzivatelia.znamenie='ryby'
GROUP BY uzivatelia.nick

a vypisuje to chybu

MySQL hlási:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( uzivatelia . uz_id = pristupy . uzivatel AND odhlasenie = 0 ) WHERE uzivateli' at line 1
vrbcik
Profil
chýbalo tam JOIN ... ON ;-) snáď to už funguje.
Toto téma je uzamčeno. Odpověď nelze zaslat.

0