Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem 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?

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
To stále bojuješ s výberom z tých tabuliek? Tie štruktúry tých tabuliek, čo si sem predtým dával, vy…
los 20.11.2014 20:45
los
Dokumentaci k tomu nemám a nejsem specialista přes DB a vůbec ne Oracle DB. <stížnost type="na živo…
Flash_Gordon 20.11.2014 20:58
Flash_Gordon
Trochu zvláštne, že tam na takéto veci nemáte databázistu. Pretože SQL príkazmi, kde budeš robiť JOI…
los 20.11.2014 21:05
los
I ke konkrétnímu datu není problém to vybrat. Stačí upravit subselect, který s horní strany omezí "b…
Jan Fiala 21.11.2014 06:45
Jan Fiala
Kluci tak posílám ty slíbené data. První je dotaz, který vytáhne správná data (bez nějakých extra f… nový
Flash_Gordon 21.11.2014 09:57
Flash_Gordon
Tak z toho druhého selektu si predsa dokážeš určiť ID z tabuľky uzivatele a tiež ID z tabuľky prava.… nový
los 21.11.2014 22:02
los
Ahoj. Zkoušet to můžu až teď. Můžeš to prosím upřesnit? Respektive můžeš tu podmínku zapsat do toho… nový
Flash_Gordon 24.11.2014 10:32
Flash_Gordon
Tak z toho druhého selektu si predsa dokážeš určiť ID z tabuľky uzivatele a tiež ID z tabuľky prava:… nový
los 24.11.2014 18:37
los
Díky, zkusím to promyslet. poslední
Flash_Gordon 24.11.2014 20:23
Flash_Gordon

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]

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"

select top 1 o.Create Date 
    from opravneni o
    where o.Uzivatel_ID = Uzivatele.id and o.Pravo_ID = prava.id and CreateDate<='20141031'
    order by o.Create_Date desc)

Kluci tak posílám ty slíbené data.

První je dotaz, který vytáhne správná data (bez nějakých extra funkcí):

SELECT *

FROM uzivatele

left join opravneni

on uzivatele.id = opravneni.uzivatel_id

left join prava

on opravneni.pravo_id = prava.id

where uzivatele.id = 17001 and opravneni.aplikace = 'MGEO'

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:

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

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.

Tak z toho druhého selektu si predsa dokážeš určiť ID z tabuľky uzivatele a tiež ID z tabuľky prava:

select
	uzivatele.id uzivatel_id,
	prava.id pravo_id
from prava
join uzivatele on 1=1
left join opravneni on uzivatele.id=opravneni.uzivatel_id and opravneni.pravo_id=prava.id;

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:

select *
from opravneni
where uzivatel_id=:uzivatel_id,
and pravo_id=:pravo_id;

Zpět do poradny Odpovědět na původní otázku Nahoru