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?

SELECT * FROM users WHERE gender = 'female' AND size > 'enough' AND leftsize = rightsize AND age >= 18 AND age < 30 LIMIT 1

Re: Dėl join funkcijos

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

3 (edited by MBIK 2006-07-03 11:52:34)

Re: Dėl join funkcijos

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?

Re: Dėl join funkcijos

MBIK wrote:

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.

MBIK wrote:

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

Re: Dėl join funkcijos

Pirmasis variantas grąžino tą pačią klaidą, o antrasis, perrašant, suveikė :) Ačiū.

Re: Dėl join funkcijos

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ų?

Re: Dėl join funkcijos

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

Re: Dėl join funkcijos

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ą.

Re: Dėl join funkcijos

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

Re: Dėl join funkcijos

Bandžiau, vistiek suskaičiuoja tik tuos, kurie visose lentelėse :(

Re: Dėl join funkcijos

Parodyk lentelių users, history11 ir history12 duomenų schemas.

12 (edited by MBIK 2006-07-03 14:17:14)

Re: Dėl join funkcijos

`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.

Re: Dėl join funkcijos

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

Re: Dėl join funkcijos

Būtent tai, ko ir reikėjo :] Tik dar name po USING turi būti skliausteliuose ;)