[megoldva] különböző tábla join annak függvényében, hogy adott érték null vagy sem

 ( cherockee | 2012. június 26., kedd - 10:26 )

Ü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

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

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.

Ahogy nézem, ez a rugalmasabb megoldás, későbbiekre elrakom, most egyelőre a case-when megoldást kipróbáljuk.

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



Szerintem jól értelmezted, gyakorlatilag a "case when ."-t kerestem.

Kipróbálom, visszajelzek.

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....
;)

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

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.

EXPLAIN kimenetet megnézném erre :)

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.

LEFT JOIN mindkét asszociációra, aztán SELECT-ben tudsz feltételeket építeni, hogy épp melyiket akarod kiolvasni, melyik nem null.

--
joco voltam szevasz

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

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.

--
joco voltam szevasz

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