Topic: Dėl join funkcijos
mysql pagrindus žinau, ką reikia pasidarau, tačiau tos join funkcijos taip ir neperkandu,
gal galėtumėtee paaiškinti kas tai per dalykas ir kur jį geriausia naudoti?
PHP ir MySQL programavimas, SQL užklausos, duomenų bazės, PHP scriptai, pagalba, diskusijos, pamokos ir straipsniai.
You are not logged in. Please login or register.
PHP ir MySQL → SQL užklausos ir duomenų struktūros → Dėl join funkcijos
mysql pagrindus žinau, ką reikia pasidarau, tačiau tos join funkcijos taip ir neperkandu,
gal galėtumėtee paaiškinti kas tai per dalykas ir kur jį geriausia naudoti?
JOIN į lietuvių kalbą išvertus reiškia "sujungti". Taigi JOIN'us naudoji, kai nori sujungti lenteles.
Tarkime turi dvi lenteles:
miestai:
id miestas
------------
1 vilnius
2 kaunas
3 klaipeda
4 siauliai
------------
vardai:
vardas is_kokio_miesto
------------------------
petras 1
jonas 2
antanas 2
jurgis 4
------------------------
Tada noredamas gauti rezultatuose du stulpelius, kurie rodytu kas yra iš kokios miesto panaudotum JOIN operaciją:
SELECT vardai.vardas, miestai.miestas
FROM vardai
INNER JOIN miestai ON vardai.is_kokio_miesto = miestai.id
Ir aš su JOIN neaiškumų turiu.
Mano supratimu, jeigu kiekvienoje sujungiamoje lentelėje yra toks pat laukas, tai galima sujungti per jį, rašant USING (`lauko_pavadinimas`).
Jei taip sujungiu dvi lenteles, būna viskas gerai:
SELECT users.name, CONCAT( history12.points + users.points ) AS overallpoints
FROM `users`
JOIN (
`history12`
)
USING ( `name` )
ORDER BY history12.points + users.points DESC
LIMIT 25
Bet jei pridedu dar vieną lentelę:
SELECT users.name, CONCAT( history11.points + history12.points + users.points ) AS overallpoints
FROM `users`
JOIN (
`history11` , `history12`
)
USING ( `name` )
ORDER BY history11.points + history12.points + users.points DESC
LIMIT 25
gaunu klaidą: #1052 - Column 'name' in from clause is ambiguous
Gal kas nors galite ją paaiškinti?
Ir aš su JOIN neaiškumų turiu.
Mano supratimu, jeigu kiekvienoje sujungiamoje lentelėje yra toks pat laukas, tai galima sujungti per jį, rašant USING (`lauko_pavadinimas`).
Taip galima.
gaunu klaidą: #1052 - Column 'name' in from clause is ambiguous
Na nesu tikras, bet gal pabandyk naudoti USING (`name`, `name`).
Arba viską perrašyti:
SELECT users.name, CONCAT( history11.points + history12.points + users.points ) AS overallpoints
FROM users
JOIN (history11) USING (name)
JOIN (history12) USING (name)
ORDER BY history11.points + history12.points + users.points DESC
LIMIT 25
Pirmasis variantas grąžino tą pačią klaidą, o antrasis, perrašant, suveikė :) Ačiū.
Dar vienas klausimas.
Dabar grąžina tik tuos įrašus, kurių name reikšmė yra visose sujungtose lentelėse. Kokios reikia užklausos, kad grąžintų jeigu vienodas name yra bent vienoje iš prijungtų lentelių?
Gal gali tiksliau paaiškinti ko tau reikia?
JOIN'ai yra keliu tipų. Standartinis ("JOIN" arba "INNER JOIN") ir yra naudojamas, kada iš lenetelių sujungiami stulpeliai, kai sujungiamasis stulpelis sutampa. Yra dar toks LEFT JOIN'as (ir RIGHT JOIN), kai iš pirmos (kairės) lenteles paimami visi duomenys, o iš dešinės tik tie, kurie sutapo.
Gali pažiūrėti manual'e ką rašo apie JOIN'us: http://dev.mysql.com/doc/refman/4.1/en/join.html
users lentelėje yra apskritai visi name variantai, o history# lentelėse - nevisi. Man reikia, kad grąžintų kiekvieno users lentelėje esančio name'o laukų points visose lentelėse sumą.
Tai bandyk kažką panašaus:
SELECT users.name,
history11.points + history12.points + users.points AS overallpoints
FROM users
LEFT JOIN (history11) USING (name)
LEFT JOIN (history12) USING (name)
ORDER BY overallpoints DESC
LIMIT 25
Bandžiau, vistiek suskaičiuoja tik tuos, kurie visose lentelėse :(
Parodyk lentelių users, history11 ir history12 duomenų schemas.
`history11`:
`name` varchar(32) NOT NULL
`points` int(11) NOT NULL default '0'
UNIQUE KEY `name` (`name`)
`history12`:
`name` varchar(32) NOT NULL
`points` int(11) NOT NULL default '0'
`users`:
`name` varchar(32) NOT NULL default ''
`points` int(7) NOT NULL default '0'
Heh, pasirodo name nėra absoliučiai identiški :)
Pasižiūrėjau, kad įrašus grąžina visus, bet jeigu kurio nors name nėra nors vienoje lentelėje, tada overallpoints būna NULL.
Na taip, mysql'e NULL + 1 = NULL ;)
Todėl reikėtu bandyti kaip nors tą NULL'a pakeisti i nulį:
SELECT users.name,
IFNULL(history11.points,0) + IFNULL(history12.points,0) + IFNULL(users.points,0) AS overallpoints
FROM users
LEFT JOIN history11 USING name
LEFT JOIN history12 USING name
ORDER BY overallpoints DESC
LIMIT 25
Būtent tai, ko ir reikėjo :] Tik dar name po USING turi būti skliausteliuose ;)
PHP ir MySQL → SQL užklausos ir duomenų struktūros → Dėl join funkcijos
Powered by PunBB, supported by Informer Technologies, Inc.