Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Oracle SQL - triviální dotaz

Dobré dopoledne.
Minule to nedopadlo úplně ideálně.

Tak jsem se inspiroval pořekadlem: Když jsi v nouzi, nejnápomocnější ruku najdeš na konci vlastního ramene.

A musím uznat, toto pořekadlo se mi v životě osvědčuje stále častěji.
Ale nyní zpět k technickému dotazu.

Vyredukoval jsem si poměrně jednoduchý SQL dotaz:

SELECT *

FROM opravneni

left join uzivatele

ON uzivatele.id = opravneni.Uzivatel_id

left join prava prav

on prav.id = opravneni.pravo_id

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

Daný dotaz funguje supr, ale má jen jedinou vadu.
Vyjede mi výsledek, kde je vazba na tabulku PRAVA.

Data, která mi vyjedou mají hodnotu true.
Ale data která nevyjedou mají hodnotu false (myslím z tabulky PRAVA!).
Dokázal by někdo tenhle SQL dotaz patchnout tak, aby se zobrazily všechny sloupce
z tabulky PRAVA? A to tak aby tam třebas přibyl sloupec oprávnění - TRUE a když tam (nyní) není, tak false?

Vyjádřil jsem se doufám dostatečně jasně?
Pokud ne, rád doplním případné dotazy.

Díky za případnou pomoc. Hlavně bych chtěl poprosti Spidera, ten se v tomhle orientuje detailně.

Předmět Autor Datum
na opravu dotazu by som potreboval vidieť ako vyzerajú tie tabuľky, ale ten problém by mal riešiť RI… nový
Alibaba2 12.11.2014 11:17
Alibaba2
Díky za nápad, ale k výsledku zdá se nevede. Pro jistotu to ještě rozepíšu přesněji. Výsledkem souč… nový
Flash_Gordon 12.11.2014 12:29
Flash_Gordon
Můžeš napsat nějaké příklady očekávaných řádků? Protože ať to čtu, jak to čtu, tak stejně nechápu, č… nový
Wikan 12.11.2014 12:37
Wikan
Jistě. Takovéto věci se nedají snadno popsat, ale já se nevzdávám. // EDIT Opravena chybka... Zákl… nový
Flash_Gordon 12.11.2014 12:48
Flash_Gordon
SELECT p.id, u.id FROM prava p LEFT JOIN opravneni o ON p.id = o.pravo_id LEFT JOIN uzivatele u ON o… nový
Wikan 12.11.2014 12:59
Wikan
Děkuji za nápad a práci! Omlouvám se za poněkud pozdější reakci, ale někdo mě tady vyrušil. Tento d… nový
Flash_Gordon 12.11.2014 13:59
Flash_Gordon
SELECT prava.*, uzivatele.*, maopravneni=case when not opravneni.Uzivatel_id is null then 'ANO' else… nový
Jan Fiala 12.11.2014 13:09
Jan Fiala
Jo jo, přepsal jsem to takhle: SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is… nový
Flash_Gordon 12.11.2014 14:05
Flash_Gordon
Dopln do WHERE podminku na aplikaci. Kdyz podminku na aplikaci odstranis, budes to mit pro vse SELE… nový
Jan Fiala 12.11.2014 14:41
Jan Fiala
Tenhle dotaz je perfektní. Funguje, ale má jednu chybku. A to tu, že poslední - nejpodstatnější slou… nový
Flash_Gordon 12.11.2014 14:57
Flash_Gordon
Uprav si ten vysledek na skutečnou hodnotu opravnění: case when not opravneni.Uzivatel_id is null t… nový
Jan Fiala 12.11.2014 15:18
Jan Fiala
Však jo, ale... ten Tvůj návrh: SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is… nový
Flash_Gordon 12.11.2014 15:44
Flash_Gordon
Teď jsem poskládal dotaz na základě vás obou, který částečně funguje. Vypadá následujícně: SELECT… nový
Flash_Gordon 12.11.2014 15:36
Flash_Gordon
Rikal jsi, ze v tabulce opravneni jsou i zaznamy pro uzivatele, kteri opravneni nemaji. To znamena,… nový
Jan Fiala 13.11.2014 07:55
Jan Fiala
No to jsme se trochu nepochopili. Podstatný je jeden detail. Tabulka PRAVA. To znamená, jsou tam ve… nový
Flash_Gordon 13.11.2014 10:48
Flash_Gordon
Pokud v tabulce opravneni neni zaznam pro pravo, ktere uzivatel mit nema, pak ti nemuze vyjizdet muj… nový
Jan Fiala 13.11.2014 11:01
Jan Fiala
Děkuji! Z tohohle se už dá dobře vycházet a já si to upravím. Pošlu nějaké $ na :beer: (podpořím P… poslední
Flash_Gordon 13.11.2014 11:24
Flash_Gordon

Díky za nápad, ale k výsledku zdá se nevede.

Pro jistotu to ještě rozepíšu přesněji.
Výsledkem současného dotazu jsou jen ty řádky s uživatelem, s oprávněními, která má povoleny.
Pokud on příslušná oprávnění nemá, tak se řádky nevypíší vůbec.

A mě jde zjednodušeně o to, aby se tam objevyly i ty řádky s oprávněními, která nemá.
Samozřejmě by tam měl být nějaký sloupeček navíc, kde bude T-True či F-False, abych se v tom vyznal(má/nemá).

Co se týče samotné struktury tabulek, tak ta vypadá takhle:

[http://pc.poradna.net/file/view/20345-tabulky-jpg]

Příkaz, který nevede k výsledku vypadal i takhle:

SELECT *

FROM opravneni

full outer join uzivatele

ON uzivatele.id = opravneni.Uzivatel_id

full outer join prava prav

on prav.id = opravneni.pravo_id

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

Jistě. Takovéto věci se nedají snadno popsat, ale já se nevzdávám.

// EDIT Opravena chybka...

Základem je tabulka PRAVA.
Tabulka PRAVA obsahuje všechny možné typy práv k různým aplikacím.
No a pak mám tabulku UZIVATELE.
Ta obsahuje všechny uživatele. Jejich oprávnění následně obsahuje tabulka OPRAVNENI.

Háček je ale v tom, že pokud uživatel právo má, tak v tabulce OPRAVNENI je vedeno.
Ovšem pokud uživatel právo nemá, tak tam vůbec vedený není!

A já potřebuji SQL dotaz, který vyjede uživatele i se VŠEMI PRÁVY.
To znamená, oproti stávajícímu dotazu tam budou navíc i ta práva a oprávnění, která nemá.

A bude samozřejmě nějak srozumitelně vyznačeno k čemu práva a k čemu Ne.

Určitě to jde nějak nesložitě naprogramovat i v Oracle SQL.
Ovšem můj znalostní záběr není neomezený.:-)

Please...

Děkuji za nápad a práci!
Omlouvám se za poněkud pozdější reakci, ale někdo mě tady vyrušil.

Tento dotaz vypíše 13 záznamů o dvou sloupcích. A u všech je vyplněno ID.

Záznamů je ale celkově 16.

A pozor, abychom to neidealizovali pouze na uživatele ID = 17001 a aplikaci 'MGEO'
Potřebuji to univerzálně pro všechny uživatele a všechny aplikace.
Tedy ne jen tyto "testovací atrapy".

SELECT prava.*, uzivatele.*, maopravneni=case when not opravneni.Uzivatel_id is null then 'ANO' else 'NE' end
FROM prava
join uzivatele on 1=1
left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.aplikace = 'MGEO'
where uzivatele.ID = 17001

podminka na aplikaci musi byt soucasti joinove podminky, jinak bys nedostal vysledek, ze uzivatel opravneni nema
prava na vsechny aplikace a uzivatele jsou formou kartezskeho soucinu (vsechny kombinace), protoze te zajima, kam vsude ma a nema uzivatel pravo
Syntaxe CASE je z MS SQL, na Oracle si to snad nejak prevedes.

Jo jo, přepsal jsem to takhle:

SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is null then 'ANO' else 'NE' end maopravneni
FROM prava
join uzivatele on 1=1
left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.aplikace = 'MGEO'
where uzivatele.ID = 17001

Tohle mi zase vyplivne neuvěřitelných 468 záznamů pro jediného uživatele.
A to je poněkud moc - oproti požadovaným 16.

Ještě to upřesním, toto testuji jen pro aplikaci MGEO (limit na 'MGEO').
Ale plánuji to na všechny aplikace (celkem 4).

Jinak díky Honzo i za PSPad, tady na něm jedu já i kolega.

Dopln do WHERE podminku na aplikaci. Kdyz podminku na aplikaci odstranis, budes to mit pro vse

SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is null then 'ANO' else 'NE' end maopravneni
FROM prava
join uzivatele on 1=1
left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.aplikace = prava.aplikace
where uzivatele.ID = 17001 and prava.aplikace='MGEO'

Pokud bys to nedelal na jednu aplikaci, byl by pocet v poradku.
Pokud je v tabulce prava seznam aplikaci, pak je to v poradku. Pokud ne (to bohuzel nevim), tak tam bude zaznamu moc.

Principem by melo byt:
seznam aplikaci x seznam uzivatelu (prvni 2 joiny) a pak pro kazdeho uzivatel a aplikaci (left outer join) dotahnes, zda ma pravo nebo ne - bud tam zazna je a pak si muzes precist pravo nebo neni, pak je opravneni.cokoliv is null

Tenhle dotaz je perfektní.
Funguje, ale má jednu chybku.
A to tu, že poslední - nejpodstatnější sloupec - maopravneni, má
pro všechny řádky hodnotu jen ANO.

A to i pro ty, které prokazatelně nemají.

EDITACE

BERU ZPĚT !

Ony tam ty hodnoty skutečně jsou. To se musím zeptat, ať si to hoši ujasní, jak to vlastně je.....

Však jo, ale... ten Tvůj návrh:

SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is null then opravneni.uzivatel_id else -1 end maopravneni

FROM prava

join uzivatele on 1=1

left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.aplikace = prava.aplikace

where uzivatele.ID = 17001 and prava.aplikace='MGEO' order by popis

Vrací narozdíl od mého předchozího příspěvku sice VŠECHNY práva, ale všechny jsou TRUE, tedy v tomhle případě opravneni.uzivatel_id.

Moje nervy z toho..... ]:(

Teď jsem poskládal dotaz na základě vás obou, který částečně funguje.

Vypadá následujícně:

SELECT prava.id, prava.popis
FROM prava
LEFT JOIN opravneni o ON prava.id = o.pravo_id
LEFT JOIN uzivatele u ON o.Uzivatel_id = u.id
WHERE COALESCE(u.id, 17001) = 17001 
GROUP BY prava.id, u.id

A chtěl bych si vyjet tímto dotazem další přidružená data z tabulky uzivatele.

Ale pokud do prvního řádku přidám třebas sloupec u.full_name,
tak mě okamžitě seřve:

NOT A GROUP BY EXPRESSION

Navíc dotaz vytahuje jen přiřazená práva, ale nepřiřazená tam zase nejsou. :-(

Dá se to nějak lehce opravit? Aby to zobrazovalo všechno, ideálně, aby vypadal první řádek vytažených sloupců:

SELECT prava.id, prava.popis, case when not opravneni.Uzivatel_id is null then 'ANO' else 'NE' end maopravneni

Rikal jsi, ze v tabulce opravneni jsou i zaznamy pro uzivatele, kteri opravneni nemaji. To znamena, ze v nejakem sloupci je hodnota, ktera urcuje, zda uzivatel ma nebo nema pravo. Prozradis nam, jmeno sloupce v tabulce opravneni a hodnoty? Pak ti muzeme poradit - viz ma posledni odpoved.

No to jsme se trochu nepochopili.

Podstatný je jeden detail. Tabulka PRAVA.
To znamená, jsou tam vedeny všechny typy PRÁV, ale uživatel(é) nemají všechny přiřazeny v OPRÁVNĚNÍ.
To znamená - nejsou všechny spárovány s uživatelem.

Vyjádřil jsem se dost jasně?

Radši ještě jednou a jednodušeji:
V tabulce PRAVA jsou všechna práva a některá z nich mají uživatelé povoleny v Oprávnění.
A uživatel je tedy spárován jen s některými typy oprávnění.

Ale já potřebuji vyjet tabulku, kde budou VŠECHNA PRÁVA a to, zda konkrétní uživatel ho má či nemá.

Když si to vyjedu jednoduchým selectem * from oprávnění teď, tak vyjedou jen taková práva a oprávnění, která uživatel = jsou spárovány s uživatelem a oprávnění. Ale úplně tam chybí ta práva, která uživatel NEMÁ.
A já jen potřebuji vyjet všechna práva a oprávnění, která má a nemá do jedné tabulky( tedy všechna práva, která tabulka práva obsahuje + oprávnění povoluje).

Pokud to mám popsat ještě v nějakém detailu, rád jej připíšu.
Ach jo.

Pokud v tabulce opravneni neni zaznam pro pravo, ktere uzivatel mit nema, pak ti nemuze vyjizdet muj select se zapisem MApravo pro agendu a akci, kam pravo mit nema.
Jednoduse z tabulky opravneni se vrati pres LEFT OUTER JOIN zaznam null.
Upravil jsem podminku napojeni opravneni

Zkus si prosim tohle:

SELECT prava.*, uzivatele.*, case when not opravneni.Uzivatel_id is null then 'ANO' else 'NE' end maopravneni
FROM prava
join uzivatele on 1=1
left outer join opravneni ON uzivatele.id = opravneni.Uzivatel_id and opravneni.pravo_id = prava.id
where uzivatele.ID = 17001 and prava.aplikace='MGEO'

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