ugrás a tartalomhoz

Kiválasztani azokat a termékeket, amik meg vannak jelölve A és B címkével, de nincs rajtuk C címke

avus · 2009. Ápr. 7. (K), 16.57
Szóval a problémám:

Termékek tábla (minden tábla egyszerűsítve)
- termekid
- termeknev

Címkék tábla
- cimkeid
- cimkenev

Kettőt összekapcsoló tábla
- termekid
- cimkeid

Ezek után szeretnék olyan lekérdezést fabrikálni, ami kiválasztja a termékek táblából mindazon bejegyzéseket, amelyek rendelkeznek A1 és A2 és ..., de nem rendelkezik B1 és B2 és ... címkékkel.

Milyen lekérdezés képes ezt az eredményt adni?
 
1

+ még valami

avus · 2009. Ápr. 7. (K), 17.07
Ezt leginkább 1 lekérdezéssel oldanám meg, ha lehet, halmazműveletek nélkül.
2

volt

gex · 2009. Ápr. 7. (K), 17.10
kerestél már a fórumban? nagyon rémlik ez a probléma és valaki írt rá egy egészen szép megoldást.
3

Join

janoszen · 2009. Ápr. 8. (Sze), 06.50
Ahány tag, annyi left join a termékekről. Ahol negálni kell, kösd ki, hogy null legyen az oszlop értéke.
5

apró trükk

Hodicska Gergely · 2009. Ápr. 8. (Sze), 09.36
Ezt leginkább 1 lekérdezéssel oldanám meg, ha lehet, halmazműveletek nélkül.
MySQL-ben nem is nagyon tudnád, mert csak az UNION van implementálva.

Ahány tag, annyi left join a termékekről. Ahol negálni kell, kösd ki, hogy null legyen az oszlop értéke.
És a teljesítmény. ;) Eég szerencsétlen megoldás több tag esetén.

Ki tudod választani azokat, amik A1 és A2 címkéjűek.
Ki tudod választani azokat, amik B1 és B2 címkéjűek.
Itt valszeg inkább B1 vagy B2-ről van szó, ami egszerűbbé teszi a feladatot, de amúgy nekem sem jut eszembe optimálisabb megoldás.
SELECT
	id
FROM
	(
		SELECT
			id
		FROM
			tag
		WHERE
			tag IN ('tag1', 'tag2')
		GROUP BY
			id
		HAVING
			count(*) = 2
	) sub
WHERE
	id NOT IN (SELECT id FROM tag WHERE tag IN ('tag3', 'tag4'))
10

Az

janoszen · 2009. Ápr. 8. (Sze), 21.44
Kérdés, hány "tag" típusú meződ van és mi a számosságuk. Játszottunk ilyesmivel az "autós" projekt kapcsán, ez volt az egyik megoldás ami viszonylag egyszerű volt, azért dobtam föl.
12

én is ;)

Hodicska Gergely · 2009. Ápr. 8. (Sze), 23.48
A left joins megoldás kb. max. 2-3 keresendő valamig tud közel lenni a group by-os megoldáshoz, utána elég rendesen esik a teljesítmény. Pl. 5 tag esetén már igencsak le tud mardni.
4

Nekem ez

deejayy · 2009. Ápr. 8. (Sze), 06.56
Nekem ez egyszerűnek tűnik.

Ki tudod választani azokat, amik A1 és A2 címkéjűek.
Ki tudod választani azokat, amik B1 és B2 címkéjűek.

Mindkét lista tartalmazza a termék id-ket, majd azt mondod, hogy kiválasztod az összes terméket, ahol "id in (elso select) and id not in (masodik select)".

A probléma ezzel csak az, hogy optimálisnak messze sem nevezhető, olykor igen sokáig futó queryket is eredményezhet.
6

aggregátor függvény postgresben

hector · 2009. Ápr. 8. (Sze), 11.00
Egyszer egy hasonló problémát úgy oldottam meg, hogy írtam egy aggregátor függvényt, ami a megadott mező értékeiből egy tömböt generált. Ezzel valami olyasmi formára hozható a lekérdezés, hogy:

SELECT   termekid, fn(cimkeid) AS cimkek
FROM     tabla
GROUP BY termekid
HAVING   'A1' IN (cimkek) AND 'B1' NOT IN (cimkek);
Az fn a saját gyártmányú aggregátor függvény. Nem biztos, hogy a HAVING rész jó, de az elv remélem érhető.
7

hali

carstepPCE · 2009. Ápr. 8. (Sze), 11.59
az en elso megoldasom fejbol kb igy nezne ki:
A1 = 1, A2 = 2, B1 = 3, B2 = 4 a tagek eseteben
SELECT id, termeknev
FROM termekek
WHERE id
IN (

SELECT termek_id
FROM tag_to_termek
WHERE tag_id
IN ( 1, 2 )
)
AND id NOT
IN (

SELECT termek_id
FROM tag_to_termek
WHERE tag_id
IN ( 3, 4 )
)
szerk: persze 200 - 500 termekig es 5-6 tag termekenkent, esetig hasznalhato, utana tovabbi optimalizacio szukseges :-)


-cs-
Sanyi
8

ez és helyett vagy

Hodicska Gergely · 2009. Ápr. 8. (Sze), 13.49
Ez a query nem jó, mert nem A1 és A2 tag meglétét követeli meg, hanem A1 vagy A2-ét.
9

...

carstepPCE · 2009. Ápr. 8. (Sze), 14.56
az en ertelmezesi hibam, bar minimalisan kell csak modositani, egyenlore csak mysql5 alatt ment at a szintaktikai elemzon :-) nincs negyesem fennt:

SELECT id, termeknev  
FROM termekek  
WHERE id  
IN ( select termek_id from tag_to_termek where tag_id in (1,6) group by termek_id having count(*) = 2 ) 
AND id NOT  
 IN (  
    SELECT termek_id  
 FROM tag_to_termek  
 WHERE tag_id  
 IN ( 3, 4 )  
 )
termeszetesen a 'having count(*) = 2' kifejezesnel, a 2 annak fuggvenyeben valtozik, hogy a termeknek hany cimket kell kotelezoen tartalmaznia, jelen esetben (1,6), tehat 2db.

szerk: talaltam egy negyeset is, azon is atmegy :-)

-cs-
Sanyi
11

Köszönöm a válaszokat, sajnos

avus · 2009. Ápr. 8. (Sze), 23.48
Köszönöm a válaszokat, sajnos ma este már zéró a felfogásom, holnap átolvasom a javaslataitokat :).