Üdv,
(Google-el nem jutottunk düllőre, "conditional join" ésatöbbi nem talált jókat.)
Feladat:
Attól függően, hogy adott sorban az "id" vagy a "mozgas" oszlopban van nem-NULL, join-olni egy adott táblát.
Történet:
Adott egy naplótábla, amiben van két féle termék, egyiknek a "gyszam", másiknak a "mozgas" táblában vannak az adatai. Gyakorlatilag egy felhasználó ID van tárolva mindkettőben.
Magyarázat:
Adott termékadatok az első 3 joinnal lejönnek, de, van a naplónak (cassa tábla) két oszlopa, egyik a "mozgas", másik az "id". Ha telefon, akkor "mozgas" oszlopban "(NULL)" van, ha tartozék, akkor "id" oszlopban van "(NULL)", és a másik oszlopokban van egy ID, ami csatolja őket (join-ok alább).
Azt kéne megoldani, hogy ez alapján csatoljuk be a táblákat, egyik sorban ezt, másikban azt, és a visszajövő felhasználó ID alapján a felhasznalo tablat is bekössük, felhasználó nevet beírjuk. Lehetőleg ugyan abba az oszlopba.
SQL képességeivel nem vagyok tisztában, hogy mennyire képes IF-eket kezelni, egy adott oszlopba beírni két külön forrásból jövő adatot, stb.
MINDEN EGYÉB MEGOLDÁSRA IS NYITOTT VAGYOK.
Alábbi próbálkozásom, amibe kéne még a feltételes csatolás:
SELECT cassa.datum, cassatip.cassatip_nev, osszeg, penzvan, prntip.prntip_nev, cassa.tetel, cassa.megjegyzes, fiztip.fiztip_nev, felhasznalo.felhasznalo, gyszam.felh_elad
FROM cassa
INNER JOIN cassatip ON cassatip.cassatip = cassa.cassatip
INNER JOIN prntip ON prntip.prntip = cassa.prntip
INNER JOIN fiztip ON fiztip.fiztip = cassa.fiztip
# ha tartozék
INNER JOIN mozgas ON mozgas.mozgas = cassa.mozgas
INNER JOIN felhasznalo ON felhasznalo.felhasznalo = mozgas.felh_id
# ha telefon
INNER JOIN gyszam ON gyszam.id = cassa.id
- 6106 megtekintés
Hozzászólások
EAV a struktúra neve, amit meg akartok valósítani.
Illetve: http://www.scribd.com/doc/2670985/SQL-Antipatterns ezt nezd vegig, lesz benne errol szo.
- A hozzászóláshoz be kell jelentkezni
Ahogy nézem, ez a rugalmasabb megoldás, későbbiekre elrakom, most egyelőre a case-when megoldást kipróbáljuk.
- A hozzászóláshoz be kell jelentkezni
Nem esküszöm meg rá, hogy jól értem, amit szeretnél, de itt egy gondolatébresztő:
select * from lx.main
ID C1 C2
----------- ---------- ----------
1 aux1 blabla1
1 aux2 blabla2
select * from lx.aux1"
ID C
----------- ----------
1 aux1data
select * from lx.aux2
ID C
----------- ----------
1 aux2data
select
id,
c1,
c2,
case
when c1='aux1' then
(select c from lx.aux1 a1 where a1.id=m.id)
when c1='aux2' then
(select c from lx.aux2 a2 where a2.id=m.id)
end as xyz
from lx.main m
ID C1 C2 XYZ
----------- ---------- ---------- ----------
1 aux1 blabla1 aux1data
1 aux2 blabla2 aux2data
- A hozzászóláshoz be kell jelentkezni
Szerintem jól értelmezted, gyakorlatilag a "case when ."-t kerestem.
Kipróbálom, visszajelzek.
- A hozzászóláshoz be kell jelentkezni
Hát ilyenért engem vágtak már "pofán". ;)
UNION - t javasolnék inkább ;)
SELECT cassa.datum, cassatip.cassatip_nev, osszeg, penzvan, prntip.prntip_nev, cassa.tetel, cassa.megjegyzes, fiztip.fiztip_nev, felhasznalo.felhasznalo, gyszam.felh_elad
FROM cassa
INNER JOIN cassatip ON cassatip.cassatip = cassa.cassatip
INNER JOIN prntip ON prntip.prntip = cassa.prntip
INNER JOIN fiztip ON fiztip.fiztip = cassa.fiztip
# ha tartozék
INNER JOIN mozgas ON mozgas.mozgas = cassa.mozgas
INNER JOIN felhasznalo ON felhasznalo.felhasznalo = mozgas.felh_id
WHERE cassa.mozgas is not null
UNION
SELECT cassa.datum, cassatip.cassatip_nev, osszeg, penzvan, prntip.prntip_nev, cassa.tetel, cassa.megjegyzes, fiztip.fiztip_nev, felhasznalo.felhasznalo, gyszam.felh_elad
FROM cassa
INNER JOIN cassatip ON cassatip.cassatip = cassa.cassatip
INNER JOIN prntip ON prntip.prntip = cassa.prntip
INNER JOIN fiztip ON fiztip.fiztip = cassa.fiztip
INNER JOIN gyszam ON gyszam.id = cassa.id
WHERE cassa.id is not null
Persze ezt még lehetne optimálisabbá tenni azért.
Mondjuk outer joinokkal....
;)
- A hozzászóláshoz be kell jelentkezni
köszönet, erre se gondoltam volna...már megszokásból nyúltam volna a php-hoz, hogy összefuttassam a két tömböt...
egyébként kis csinosítással működik
- A hozzászóláshoz be kell jelentkezni
Ahhoz kétség nem fér, hogy ez könnyebb falat, amíg nincs annyi ág, hogy hogy sql text lenth limitbe ütközzön az ember - mert akkor meg azért kap a képire.
- A hozzászóláshoz be kell jelentkezni
EXPLAIN kimenetet megnézném erre :)
- A hozzászóláshoz be kell jelentkezni
Optimalizáló kérdése az egész.
Kis reklám a DB2-nek...
...
Kicsit belegondolva: könyebb súlycsoportú motoroknak sem okozhat nagy gondot, nincs benne semmi mágia.
- A hozzászóláshoz be kell jelentkezni
LEFT JOIN mindkét asszociációra, aztán SELECT-ben tudsz feltételeket építeni, hogy épp melyiket akarod kiolvasni, melyik nem null.
- A hozzászóláshoz be kell jelentkezni
SELECT-ben aligha tud felteteleket epiteni a JOIN-olt cuccokra. WHERE-ben azonban...
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
select isnull(tabla1.x, tabla2.y) from fotabla left join tabla1 left join tabla2
vagy case when tabla1.id is not null then 'elso sikerult' when tabla2.id is not null then 'masodik sikerult' else 'egyik sem sikerult' end
stb.
- A hozzászóláshoz be kell jelentkezni
Ezt az ISNULL-as játékot csináltam én is hasonló esetben, nálam teljesen jól működik, igazából 5-ágas esetre (tehát 5 táblát kellett csatolgatni).
- A hozzászóláshoz be kell jelentkezni