ugrás a tartalomhoz

Értékek egy csoportját tartalmazó sorok lekérése

Dualon · 2008. Ápr. 17. (Cs), 22.21
Környezet: MySQL 4.1, Apache 2.0.2 (Ubuntu 7.10)
Adatbázis-háttér:
CREATE TABLE gyumolcsok (
gyumolcs_id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
gyumolcs_nev VARCHAR(10) NOT NULL);

CREATE TABLE kukacok_gyumolcsokben (
gyumolcs_id TINYINT UNSIGNED NOT NULL,
kukac_id TINYINT UNSIGNED NOT NULL);

INSERT INTO gyumolcsok (gyumolcs_id, gyumolcs_nev) VALUES
(1, 'alma'),
(2, 'korte'),
(3, 'barack'),
(4, 'cseresznye');

INSERT INTO kukacok_gyumolcsokben (gyumolcs_id, kukac_id) VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(2, 1),
(2, 3),
(2, 4),
(2, 6),
(3, 1),
(3, 2),
(3, 5),
(4, 1),
(4, 2),
(4, 3);
Cél: Keresem azon gyümölcsök neveit, amelyekben mondjuk az 1-es és 3-as kukac is megtalálható (alma, korte, cseresznye).
Kukacfajtából lehet sok-sok (akár több tucat is), vagyis a többszörös JOIN, UNION szerintem nem megoldás.

Ameddig jutottam:
SELECT gyumolcs_nev FROM gyumolcsok WHERE gyumolcs_id IN (SELECT gyumolcs_id FROM kukacok_gyumolcsokben WHERE kukac_id IN(1, 3) GROUP BY gyumolcs_id)
Ez nyilvánvalóan rossz, mivel nem a kukac_id-k metszetét, hanem únióját adja (a 'WHERE kukac_id IN(1, 3) GROUP BY gyumolcs_id' feltétel rossz).

Amit próbáltam: Google, Weblabor, MySQL manual, sok-sok próba GROUP BY-jal és testvéreivel. :)

Végeredményben azzal már boldog lennék, ha tudnám, hogyan lehet lekérni azon sorokat, melyek összességében tartalmazzák egy érték-csoport értékeit (esetünkben azon sorokat, melyek pl. az 1-es és 3-as kukac_id-ket).
Elnézést kérek, ha láma dolgot kérdezek, az esetleges segítséget pedig előre is köszönöm!
 
1

nem probaltam ki

Protezis · 2008. Ápr. 18. (P), 00.57
SELECT gy.gyumolcs_nev FROM gyumolcsok gy INNER JOIN kukacok_gyumolcsokben kgy ON gy.gyumolcs_id=kgy.gyumolcs_id WHERE kgy.kukac_id IN (1,3)
2

Ez sajnos szintén únió

Dualon · 2008. Ápr. 18. (P), 14.43
Szerintem a megoldásod lényegében azonos az általam fentebb vázolttal. Ki is próbáltam, sajnos tényleg szintén úniót ad.

Mindenesetre köszönöm, hogy foglalkoztál vele! Ha esetleg van még ötlet, örömmel fogadnám.
3

subquery jó

griphons · 2008. Ápr. 18. (P), 15.20
de minek a végét megbonyolítani?
SELECT gyumolcs_nev FROM gyumolcsok WHERE gyumolcs_id = (SELECT gyumolcs_id FROM kukacok_gyumolcsokben WHERE kukac_id = 1 OR kukac_id = 3);
nem próbáltam ki, de ennek mennie kéne, a mysql manuál szerint ez a szintaxis
4

Ez is únió

Dualon · 2008. Ápr. 18. (P), 17.05
A subquery több sort ad vissza, ezért nem használható az outer query-ben a gyumolcs_id=() feltétel.
Másrészt a több OR az eredmény szempontjából megfelel az IN-nek (noha sokkal hosszabb és szvsz kevésbé elegáns query-t eredményez), vagyis ekkor továbbra is azon gyümölcsöket fogja megtalálni, amelyekben 1-es VAGY 3-as kukac van, nem pedig azokat, melyekben 1-es ÉS 3-as kukac is.
Az AND értelemszerűen nem használható, mert nincs olyan sor a kukacok_gyumolcsokben táblában, melyre igaz lehetne a kukac_id=1 AND kukac_id=3 feltétel (egy sor csak egyféle kukac_id-t tartalmazhat).

A subquery-vel tehát azon gyumolcs_id-ket szeretném megkapni, melyeknek megfelelő sorok teljes halmazában van 1-es és 3-as kukac_id egyaránt.

Mindenesetre köszönöm neked is a fáradozást!
12

bocsi :)

griphons · 2008. Ápr. 22. (K), 14.55
Igazad van, bocsi ezt jól benéztem.
Most is tanultam vmit :)
5

Minden kukac 1 join

siposa · 2008. Ápr. 18. (P), 17.36

select g.* from kukacok_gyumolcsokben j1 
 inner join kukacok_gyumolcsokben j3 
   on j3.kukac_id=3 and j3.gyumolcs_id=j1.gyumolcs_id
 inner join gyumolcsok g on g.gyumolcs_id=j3.gyumolcs_id
where j1.kukac_id=1
7

Több tucat join szerintem nem hatékony

Dualon · 2008. Ápr. 20. (V), 12.58
A témaindító bejegyzésemben írtam, hogy adott esetben több tucat kukacféle is lehet a gyümölcsben:
Kukacfajtából lehet sok-sok (akár több tucat is), vagyis a többszörös JOIN, UNION szerintem nem megoldás.


A fentiek miatt vetettem el ezt az utat.
Persze meggyőzhető vagyok, hogy hatékonyabb, mint két lekérés eredményeit összefésülni. :)

Köszönöm a választ!
10

No problem

siposa · 2008. Ápr. 21. (H), 10.22
Hát akkor több tucat join lesz. Semmi baja nem lesz a gépednek, dolgozzon meg szépen a pénzéért... :)
6

Többszörös JOIN

Rici · 2008. Ápr. 18. (P), 17.40
Már láttam jónéhány SQL lekérdezést, én azt mondanám, hogy ezt jó eséllyel csak többszörös JOIN-nal tudod megoldani, mégpedig annyival, ahány sorral párosítva kell lennie a gyümölcsnek. Aki tud más megoldást az szóljon, kíváncsian várom (a JOIN-ok egyszerű átírása AND művelettel összekötött alkérésekre nem ér...)

SELECT gy.gyumolcs_nev
FROM gyumolcsok gy, kukacok_gyumolcsokben k1, kukacok_gyumolcsokben k2
WHERE gy.gyumolcs_id = k1.gyumolcs_id
  AND gy.gyumolcs_id = k2.gyumolcs_id
  AND k1.kukac_id = 1
  AND k2.kukac_id = 3


8

Többszörös join elvetése - l. fentebb

Dualon · 2008. Ápr. 20. (V), 13.01
Sajnos erős a gyanúm, hogy a leghatékonyabban ezt csak két lekérésből fogom tudni megoldani.
Fentebb írtam, hogy akár több tucat kukac is kellhet egy gyümölcsnél, emiatt a többszörös join szerintem nem szerencsés.

Mindenesetre köszönöm neked is a választ!

Ha pedig valakinek van jobb ötlete, azt örömmel fogadnám.
9

Két lekérés?

Rici · 2008. Ápr. 20. (V), 18.33
Ezt hogyan oldanád meg többszörös JOIN nélkül két lekéréssel?

A JOIN nem hiszem, hogy probléma lenne, persze egy jó helyre rakott index használatával együtt.
13

Többszörös JOIN nélkül

Rici · 2008. Ápr. 25. (P), 21.21

SELECT gy.gyumolcs_id, gy.gyumolcs_nev   
FROM gyumolcsok gy, kukacok_gyumolcsokben k
WHERE gy.gyumolcs_id = k.gyumolcs_id   
      AND k.kukac_id IN (1,3)
GROUP BY gy.gyumolcs_id, gy.gyumolcs_nev   
HAVING COUNT(*) = 2
Ahol az IN után a kérdéses lista van, a HAVING-nél pedig a lista elemszáma. Persze feltétel, hogy a kukacok_gyumolcsokben tábla két mezője elsődleges kulcsot alkosson.
11

aggregátor függvény

hector · 2008. Ápr. 21. (H), 15.47
Nem ismerem a MySQL képességeit, de csinálnék egy aggregátor függvényt, ami a GROUP BY során a kukac_id-kből egy tömböt hoz létre. Így SELECT után kapsz egy olyan recordset-et aminek az első oszlopában a gyumolcs_id van, a másodikban pedig egy tömb, ami az adott gyümölcsben lévő kukacok fajtáit tartalmazza. Ezt megtoldva egy WHERE-rel ki is szűrhetők az általad kívánt elemek (egy lekérdezésben egy JOIN-nal).
(postgresben így: http://www.postgresql.org/docs/8.1/interactive/xaggr.html)

szerk.: rákerestem Google-ben, lehet MySQL alatt is aggregátor függvényt csinálni, viszont úgy tűnik, nem tud visszatérési értéknek tömböt: http://dev.mysql.com/doc/refman/5.0/en/create-function.html