
Oracle SQL - kde je chybka v dotaze
Čau.
Prosím Warm_Spidera nebo někoho podobného o pomoc s podmínkou.
Mám poměrně jednoduché SQL:
SELECT * FROM opravneni left join uzivatele
on opravneni.uzivatel_id = uzivatele.id
order by uzivatel_id, aplikace
Výše uvedené SQL propojuje 2 tabulky.
A výstupem jsou taková oprávnění, která má uživatel přiřazena.
No ale pozor, nejedná se o všechna možná oprávnění.
A já chci dotaz, který zobrazí i ta práva, která uživatel nemá (třetí tab. prava).
Na to mám tenhle dotaz:
SELECT uzivatele.id user_id, prava.create_date , uzivatele.disabled blokovan ,uzivatele.username, uzivatele.full_name, prava.popis mujpopisek, prava.aplikace , case when not opravneni.Uzivatel_id is null then '1' else '0' end maopravneni, TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY HH:MI') Vypis_stavu_k
FROM prava
join uzivatele on 1=1
left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.pravo_id = prava.id order by uzivatele.id , prava.aplikace, maopravneni, popis
Ale tento zápis má dvě podstatné vady:
1) oprávnění jsou v čase přidávána a měněna.
Tzn. vytáhnout chci jen to, co přibylo naposledy (v tab. oprávnění, sloupec Create_date)
2) Je tam nějaká drobná chyba
Vlivem této chyby se u jediného oprávnění rozchází výsledek se skutečností.
Konkrétně jde o právo, které nemá uživatel přiřazeno(není v tabulce opravneni), ale
ve výsledku je vedeno jako, že ho má
Čím to ještě může být?
abys do toho dostal posledni zadane opravneni, musis si subselectem vytahnout nejvyssi datum
Ale nevím, jak to přesně přepsat do Oracle
A co se týká té chyby, bez toho, že bych si to na datech zkusil ti fakt neporadím, protože nevím co se tam zobrazí chybně a nemám možnost si dohledat proč.
Díky alespoň za toto.
Zítra to budu moci otestovat a poskytnout feedback.
To stále bojuješ s výberom z tých tabuliek? Tie štruktúry tých tabuliek, čo si sem predtým dával, vyzerajú ako z nejakého dátového skladu. V nich sa historické dáta ukladajú rôznymi spôsobmi, viď Slowly Changing Dimension (SCD).
Píšeš, že sa v tabuľke uchováva aj história, len mi nie je celkom jasné, že ako. To o platnosti poľa rozhoduje vážne len ten stĺpec CREATE_DATE? O čom presne hovorí hodnota v stĺpci UPDATE_DATE? Ak je význam CREATE_DATE a UPDATE_DATE taký, že odkedy dokedy platia údaje v danom riadku, tak potom ide o SCD typu 2.
Pointa práce s takýmito dátami je v tom, že by si si nemal pýtať najnovšie dáta, ale dáta ku konkrétnemu (aktuálnemu) času. Malo by ti to podstatne zjednodušiť SQL príkazy, ktorými získavaš aktuálne dáta.
Edit: Nemáš to náhodou tak, že UPDATE_DATE je len pri aktuálnom zázname rovné NULL? To by si mal potom ešte jednoduchšie.
Dokumentaci k tomu nemám a nejsem specialista přes DB a vůbec ne Oracle DB.
<stížnost type="na život">
<ul>
<li>
Jsem jen taková děvečka na všechno, sedmé kolo u vozu.
</li>
<li>
Jednoduše takový šu*í*k, použitelný i jako universální hromosvod.
</li>
</ul>
</stížnost>
Rozložení využitých tabulek (označené) vypadá takhle:
![[http://pc.poradna.net/file/view/20513-tabulky-jpg]](/file/view/20513-tabulky-jpg)
Zítra se pokusím vložit v rámci možností nějaký sampl dat, pro případ, že to fungovat nebude ani potom.
Trochu zvláštne, že tam na takéto veci nemáte databázistu. Pretože SQL príkazmi, kde budeš robiť JOIN cez tabuľky s vnoreným SELECTom, v ktorom je ORDER BY, môžeš celú databázu takpovediac zabiť. Ono nepotrebuješ na toto ani nejakú dokumentáciu, len sa proste pozri, ako sa vypĺňa ten stĺpec UPDATE_DATE. Ak je pri najnovších hodnotách nastavený na NULL (prípadne nejaký dátum typu 31.12.9999), tak aktuálnu hodnotu získaš úplne jednoducho.
I ke konkrétnímu datu není problém to vybrat. Stačí upravit subselect, který s horní strany omezí "budouci data"
Kluci tak posílám ty slíbené data.
První je dotaz, který vytáhne správná data (bez nějakých extra funkcí):
Tento dotaz (výsledek) je v přiloženém XLS dokumentu na prvním listu.
Na druhém listu je výsledek z poskládaného SQL:
Zde vše sedí až na žlutý řádek, kde je z nějakého důvodu chyba.
Pochopitelně jsem zkoušel i Honzův SQL (první příspěvek), ale ten hlásí:
FROM keyword not found where expected
A odkazuje se na oblast vnořeného selectu v závorce.
(Chybku s pojmenováním opravneni op jsem si opravil)
Tak z toho druhého selektu si predsa dokážeš určiť ID z tabuľky uzivatele a tiež ID z tabuľky prava. Potom by si nemal mať problém zistiť, že ktorý záznam z tabuľky opravneni spôsobil to, že tam máš ten riadok navyše.
Podľa mňa to bude súvisieť s tým, že v prvom selekte obmedzuješ výber podľa opravneni.aplikace, čo v druhom selekte nevidím.
Ahoj.
Zkoušet to můžu až teď.
Můžeš to prosím upřesnit? Respektive můžeš tu podmínku zapsat do toho dotazu?
dík
Tak z toho druhého selektu si predsa dokážeš určiť ID z tabuľky uzivatele a tiež ID z tabuľky prava:
Potom by si nemal mať problém zistiť, že ktorý záznam z tabuľky opravneni spôsobil to, že tam máš ten riadok navyše:
Díky, zkusím to promyslet.