ziele - isabel

Werbung
Einführung in Datenbanken
Semester: IV
DATENBANKEN I
Semester 4
Mitgeschrieben von: Isabel Drost, If99w1
Mitschrift von: Drost, Isabel/ if99wp1
Seite 1 von 23
Einführung in Datenbanken
Semester: IV
Inhaltsverzeichnis:
ZIELE: ___________________________________________________________________4
Mittel(SE):_________________________________________________________________4
Aufgaben: _________________________________________________________________4
SQL – formale Sprache __________________________________________________________ 4
Oracle SQL+: ______________________________________________________________4
Data Types_________________________________________________________________5
Konkrete Operationen _______________________________________________________5
Projektionen - Spaltenauswahl ____________________________________________________ 5
SCOTT
........ Lsg.: SELECT ename „Name“, ‚........‘ „Unterschrift“ __________________________ 5
Selection – Auswahl von Zeilen____________________________________________________ 6
Wildcards__________________________________________________________________6
Ordnung __________________________________________________________________7
Mengen ___________________________________________________________________7
Nullwerte __________________________________________________________________8
Join ______________________________________________________________________8
Outer Join _____________________________________________________________________ 9
AutoJoin ___________________________________________________________________________ 10
TetaJoin Θ __________________________________________________________________ 10
BETWEEN – Operator _________________________________________________________ 10
Das Karthesische Produkt ___________________________________________________10
Subquery _________________________________________________________________11
Typische Subquery Fehlermeldung: ______________________________________________ 11
EXITSTS_____________________________________________________________________ 12
FOR ALL-Ersatz ______________________________________________________________ 12
Mehrfach SQ _________________________________________________________________ 12
SQs und Mengen ______________________________________________________________ 13
SQs und Joins _________________________________________________________________ 13
Rekursive SQs ________________________________________________________________ 14
Ausdrücke und Funktionen __________________________________________________14
WHERE i.OrdID=o.OrdID _____________________________________________________________ 14
Arithmetik ________________________________________________________________15
StringOperationen _________________________________________________________15
CharakterStrings: _____________________________________________________________ 15
Konktination: _________________________________________________________________ 15
Decode: ______________________________________________________________________ 15
Mitschrift von: Drost, Isabel/ if99wp1
Seite 2 von 23
Einführung in Datenbanken
Semester: IV
Substrings: ___________________________________________________________________ 15
Upper und Lower: _____________________________________________________________ 15
Intr: _________________________________________________________________________ 15
Initcap: ______________________________________________________________________ 15
Dump: _______________________________________________________________________ 16
SoundEX: ____________________________________________________________________ 16
Formatierung von Spalten_______________________________________________________ 16
Statistikfunktionen von Oracle: __________________________________________________ 17
Tabellen in Bäume wandeln _____________________________________________________ 18
SELECT prodid FROM________________________________________________________________ 19
(SELECT prodid, startdate, enddate from price where prodid=100861)___________________________ 19
Debugging ________________________________________________________________20
Reports___________________________________________________________________21
Tables erstellen und updaten _________________________________________________22
Mitschrift von: Drost, Isabel/ if99wp1
Seite 3 von 23
Einführung in Datenbanken
Semester: IV
Datenbanken
Klausur:
alles verwendbar
zB. Ausarbeitung
ZIELE:
DBMS: Oracle-benutzen
Relationale Strukturen von DB-beherrschen
Linua Franca (Verkehrssprache): SQL-Syntax/Semantik lernen
am Rechner (mit neuer DB)
2/ 3 Theoriefragen (praxisbezogen)
Dabei interessieren nicht die Ergebnisse
sondern vielmehr der Selecht selber
Mittel(SE):
Durchschnitt:2,5/ 3,5
Paradigmat. Einf. in SQL
SQL-Syntax by doing
Bsp. nachvollziehen
DB-Bsp.: SCOTT/TIGER
Protokollieren (Probl.,Lösg.,Syntax)
Arbeit mit Oracle (nt, sql+)
Doku siehe IntranetHP
Aufg mögl. selbstständig
Antizipation (sql selbstständig)
Oracle kostenfrei über FH zu beziehen
Keine Aufgabensammlung Ziel: eigene
Aufgaben finden
Aber: Bsp.Db verfügbar
Mitschreiben via Spooling oder Cut&Paste
mit Word
Aufgaben:
- Ausarbeiten der SeminarNotizen (KlausurVorbereitung)
- Üben von SQL mit oracle (auch andere Bsp.-DB)
- Zusammenhang mit Theorie herstellen (VO)
Login=Novell/ Unix
Paßw=(siehe Novell ;-) )
Host=RIES, ZUSE
SQL – formale Sprache
(hat Syntax, Semantik, Pragmatik)
The only way, to learn a programming lang. Is by writing programs in it. (Kernighan ;-) )
•
Prozedurale Sprache
Oracle SQL+:
•
•
Environmenteinstellungen über Options
I:\oracle = pwd
(shift-rechteMaustaste-openwith)
Datenbankaufbauende Dateien:
H:\Praktiku\Datenba\O8
START demo_bld
SELECT * FROM cat;
•
•
•
•
•
•
•
•
•
•
•
demo_bld.spl, demo_drp.sql
ergibt alle Einträge
SQL – Befehle kommen in den Buffer, werden dort abgearbeitet
R(un)
wiederholt Befehl im Buffer (bei vergessenem ; - Befehl steht immernoch im Buffer)
L(ist)
zeigt Befehl im Buffer
EDIT
öffnet den SQL – Buffer im Editor
SAVE xyz
(xyz = Dateiname) speichert den Befehl
GET xyz
holt den Befehl in den SQLBuffer, der von dort via R ausgeführt werden kann.
HELP
hier zusätzlich installiert – oracle6, reicht meist aus
Bei Error:
Errormessage, Sternchen steht an der Stelle, wo der Fehler steht
RollBack
macht Befehle rückgängig, erst mit Ausloggen werden Änderungen permanent
COMMIT
macht Befehle explizit permanent
SELECT *FROM cat; gibt alle Tabellennamen aus
Mitschrift von: Drost, Isabel/ if99wp1
Seite 4 von 23
Einführung in Datenbanken
Semester: IV
Data Types
•
•
•
•
•
•
NUMBER (entspricht INT, REAL, ... )
(die anderen können auch verwendet werden – aus Kompatibilitätsgründen mit eingebaut)
CHAR(), VAR CHAR()
- Char: String wird auf volle Länge mit Leerzeichen aufgefüllt, mit VARCHAR nicht
- Bsp: CHAR: ‚SMITH____‘ (bei CHAR(10))
DATE (Datum, nach außen ein String, der aber auf Korrektheit des Datums geprüft wird)
- Datum wird auf Korrektheit geprüft
- Zeit mit integrierbar
- Basierend auf Julian. Kalender
- Operationen: Addition eines Monats, „Gib‘ mir nächsten Tag, der auf morgen folgt“ etc.
RAW („rohe Daten“)
- Binärdaten, wie Bilder etc.
- Systemspezifisch und weniger kompatibel
- Kaum von SQL+ unterstützt, lesen und eingeben nur via hex
LONG CHAR, LONG RAW (char und raw vergrößert auf einige Gigabyte)
LOB (large object binary)
Multimedia sollte mit in Beleg, wens
- für Multimediaanwendungen
ein/ zwei Bildchen etc.
- CLOB -> CHAR (an jedem System identisch)
- NCLOB -> N=national languagesupport
- BLOB -> binary LOB (für Bilder & Sound)
- zwei Varianten: einmal einfügen als Datei oder direkt in die DB
DESC emp – beschreibt den Inhalt , gibt z.B. auch den Datentyp mit aus.
Konkrete Operationen
Projektionen - Spaltenauswahl
SELECT ename, sal, job FROM emp;
SELECT DISTINCT job FROM emp;
Ausgabe von Name, Gehalt, Job der Datenbank
Ausgabe aller Jobs, Distinct streicht dabei alle genau gleichen Zeilen
raus
SELECT ename, sal, ‚Dollar‘ FRO...;
Ausgabe von normalem Text in den ‚...‘ , dieser Text gilt als
Überschrift
SELECT ename Name,... FROM emp;
temporäres Umbennen der Spalte in Name, Umschrift in
Großbuchstaben, keine Leerzeichen oder Operationszeichen möglich
SELECT ename „Name“, ... FROM...;
Alles wird so ausgegeben, wie’s dasteht-> auch Leerzeichen und
Operationszeichen möglich
Bei anderen System gehört ein AS zwischen den Titel der Spalte und dem neuen Namen.
1. Aufgabe: Unterschriftenliste
Name Unterschrift
SCOTT ........
Lsg.: SELECT ename „Name“, ‚........‘ „Unterschrift“
Mitschrift von: Drost, Isabel/ if99wp1
Seite 5 von 23
Einführung in Datenbanken
Semester: IV
Selection – Auswahl von Zeilen
SELECT *FROM emp WHERE deptno=30;
Gib all die Leute aus, die in Departement# 30 wohnen, gibt
ganze Zeilen aus
SELECT 'true' " " FROM emp WHERE
ename='SCOTT';
Gib true aus, wenn es einen Scott gibt
SELECT * FROM emp WHERE sal>2000;
Vergleichsoperatoren: <; <=; >; >=; !=; <>
Wer verdient denn mehr als 2000 Dollar?
SELECT * FROM emp WHERE comm>=sal;
Mindestens soviel Comm wie sal
SELECT * FROM emp WHERE sal>2000 and deptno=20;
Mehr als 2000$ und sie leben in Departement 20
SELECT * FROM emp WHERE job='CLERK' or job='MANAGER';
Zeige alle, die entweder Manager, oder Clerk sind.
SELECT *FROM emp WHERE deptno='10' and (job='CLERK' or job='MANAGER');
Wohnen in Departement 10 und haben entweder den einen,
oder den anderen Job
SELECT *FROM emp WHERE deptno='10' and (job!='CLERK' and job!='MANAGER');
Wohnen in Departement 10 und sind nicht Manager oder
Clerk
SELECT *FROM emp WHERE deptno=10 and (job<>'CLERK' and job<>'MANAGER');
Siehe oben ;-)
Oder ohne Verwendung von nicht: Verwendung von De’Morgan.
SELECT *FROM emp WHERE sal BETWEEN 1200 and 1400;
Zwischen 1200 und 1400 (einschließlich der Grenzen)
SELECT *FROM emp WHERE job in ('MANAGER','CLERK');
Job Element von {Manager, Clerk}
SELECT *FROM emp WHERE job not in ('MANAGER','CLERK');
Wildcards
Unix
„*“
„?“
SQL
„%“
„_„
Beliebig viele beliebige Zeichen
Beliebiges Zeichen
ename =‚S%‘
ename LIKE ‘S%‘
Suche alle die, die mit S beginnen und mit % aufhören
Suche alle die, die mit S beginnen
Mitschrift von: Drost, Isabel/ if99wp1
Seite 6 von 23
Einführung in Datenbanken
Semester: IV
Ordnung
Reihenfolge bei einem normalen Select ist beliebig.
ORDER BY ename
ORDER BY ename DESC
ORDER BY job, sal DESC, ename
ORDER BY LENGHT (ename)
ORDER BY 2
ordne nach ename, aufsteigend alphabet oder numerisch
absteigende Anordnung
mehrmals der gleiche Job->ordne absteigend nach Gehalt
dann nach ename
Nach der Länge sortieren
Sortiere nach der 2. ausgewählten Spalte
ORDER BY DECODE (Spalte, die dekodiert werden soll; Inhalt, Position; Inhalt, Position;...)
Inhalt einer Spalte in anderer Reihenfolge anordnen
SELECT *from emp order by decode(deptno, 30,3,20,1,10,2);
Mengen
Union
Intersect
Minus
SELECT ename, job FROM emp UNION SELECT dname, loc FROM dept;
Suche die Jobs, wo die deptno 10 und 20 ist:
SELECT job FROM emp WHERE deptno=10 UNION SELECT job FROM emp WHERE deptno=20;
Weise nach, dass union ein DISTINCT impliziert:
CREATE TABLE emph AS SELECT *FROM emp;
INSERT INTO emph SELECT *FROM emp;
SELECT *FROM emph union SELECT *FROM emph;
Erstellen einer neuen Tabelle, die wie emp
aussieht, nur ohne Primary key
Vereinigt die Einträge aus der neuen Tabelle, dabei
werden doppelte Einträge rausgefiltert-> implizites
DISTINCT
SELECT *FROM emph union ALL SELECT *FROM emph;DISTINCT ausschalten
Finde die Aufgabe heraus:
SELECT job FROM emp WHERE deptno=10 INTERSECT ... deptno=20;
Gibt die Jobs aus, die sowohl in Departement 10
als auch 20 da sind. Bei Minus, die die weder bei
10 noch 20 sind
Bei gleichen Spaltennamen muß zum Ordnen die Spaltennummer angegeben werden.
Mitschrift von: Drost, Isabel/ if99wp1
Seite 7 von 23
Einführung in Datenbanken
Semester: IV
Was passiert bei: A/B U C
wird mit Klammern eindeutig, sonst von oben nach unten
Gleichheit von Mengen:
Wenn zwei Tabellen gleich sind, kann ich ja eine wegschmeißen. Mathemat. Definition ist folgende: A
Teilmenge von B und B Teilmenge von A. Ausgedrückt mit Minus: A\B UNION B\A = 0.
(SELECT *FROM emph MINUS SELECT *FROM emp)UNION(SELECT *FROM emp MINUS SELECT
*FROM emph);
DELETE emph WHERE ename='SMITH';
(SELECT *FROM emph MINUS SELECT *FROM emp)UNION(SELECT *FROM emp MINUS SELECT
*FROM emph);
- bringt die vorher gelöschte Zeile ans Tageslicht, die jetzt nur noch in emp enthalten ist
Nullwerte
Werte, die unbekannt sind, sind nicht gleich NULL !
SELECT *FROM emp WHERE comm=NULL;
no rows selected
Erklärung: Vergleiche einen Wert, den Du angucken kannst
und vergleiche ihn mit dem Fakt, dass er nicht da ist. Ist
semantischer Blödsinn.
SELECT *FROM emp WHERE comm IS NULL;
liefert hier die richtige Ausgabe.
Wenn wir all die wollen, die nicht Null sind:
SELECT *FROM emp WHERE comm IS NOT NULL;
Tautologien:
SELECT ... WHERE comm=comm;
Dürfte immer wahr sein, Tautologie. Gibt aber nicht alle 14 Zeilen
aus: die, die nicht definiert sind, werden nicht ausgegeben.
SELECT *FROM emp WHERE comm>1000 OR comm<=1000; (siehe oben)
Sowas kann notwendig sein, wird vom OracleSystem aber nicht wirklich unterstützt, da es anscheinend eine
dreiwertige Logik verwendet. Ausprobieren hilft gegen’s auf die Nase fliegen.
Join
Aufteilung von einer Tabelle in mehrere, um Redundanz zu vermeiden. Z.B. Einführung einer Nummer für’s
Department und Extratabelle für die Departmentnamen.
SELECT ename, loc FROM emp, dept;
Bringt alle Jobs kombiniert mit
allen Dept#
SELECT ename, loc FROM emp, dept WHERE deptno=deptno;
Bringt Fehler: mehrdeutig.
SELECT ename, loc FROM emp, dept WHERE emp.deptno=dept.deptno;
Entfernt Mehrdeutigkeit, da die
Tabellen direkt angesprochen
werden.
SELECT ename, loc, dept.deptno FROM emp, dept WHERE emp.deptno=dept.deptno
Gibt auch die Nummer selber mit
aus.
SELECT e.deptno FROM emp e, dept d;
Mitschrift von: Drost, Isabel/ if99wp1
Bei langen Tabellennamen ist
deren Umbenennung möglich.
Seite 8 von 23
Einführung in Datenbanken
Semester: IV
SELECT emp.*, loc FROM emp, dept WHERE emp.deptno=dept.deptno;
Dann ist aber der Zugriff über
emp.x nicht mehr möglich.
Gibt alle Zeilen aus emp aus und
loc aus dept. Allerdings
kombiniert er nur sinnvoll (nur
die, wo die Departmentnummern
übereinstimmen.)
Läßt man die join Bedingung weg, ergibt dies ein karthesisches Produkt. Vorgeschlagene Reihenfolge für den
Selectaufbau:
1.
2.
3.
SELECT
SELECT
SELECT xxx
FROM xxx
FROM xxx
FROM xxx
WHERE xxx
WHERE xxx
Reihenfolge der angegebenen kann für die Performance von Relevanz sein. Ein gutes System sollte hier
optimieren und die ideale Reihenfolge verwenden.
JOINs dieser Art („=“ in der JOINBedingung hinter dem WHERE) heißen Equi-Joins. Semi-Joins hingegen
verwenden die Tabellen, zeigen aber von der zweiten Tabelle nichts an. (häh? Wie jetzt?)
Ach, so: nur was aus der ersten Tabelle und nix aus der zweiten Tabelle. Dazu wird erstmal das karthesische
Produkt entfernt (joinBedinung). Hier wird auch der Angestellte nicht doppelt ausgegeben, dadurch dass
DISTINCT angegeben wurde.
SELECT DISTINCT ename FROM emp, customer WHERE (emp.empno=customer.repid)
Outer Join
Ziel:
Gib alle Zeilen zweier Tabellen aus. Dabei soll es möglich sein, Zeilen auszugeben, die nach der joinBedingung
kein Pendant haben. Z.B. gibt es mehr Departments als Angestellte. Ich will also alle Departments und dazu alle
Angestellten.
SELECT *FROM emp,dept WHERE emp.deptno(+)=dept.deptno
Select dname,ename,name from emp,dept,customer where dept.deptno=emp.deptno(+) and
emp.empno=customer.repid(+)
Wählt alle Departments aus, dazu alle passenden Angestellten und dazu
wiederum alle Kunden.
Schwierigkeit hierbei ist, dass es Departments ohne Angestellte gibt, dass es
Angestellte ohne Kunden gibt, die aber alle ausgegeben werden sollen.
Deshalb der (+) (outer Join) – Operator. Dieser gibt auch alle die Einträge
einer Tabelle aus, die der passenden Tabelle kein Pendant haben.
INSERT into emp (empno,ename,deptno) Values (7,'Bond',NULL);
Einfügen neuer Werte – geht nicht, da deptno nicht null sein darf.
ORA-01400: cannot insert NULL into ("IDROST"."EMP"."DEPTNO")
INSERT into emp (empno,ename,deptno) Values (7,'Bond',70);
Geht nicht, da es keinen ParentKey in der anderen Tabelle gibt. Somit kann
es nicht passieren, dass z.B. in einer Bibliothek ein Buch von jemandem
ausgeliehen wird, den es gar nicht gibt (wenn ich den, der es ausgeliehen hat,
über den PrimaryKey identifiziere, muß es diesen ja auch geben, sonst kann
es mir ja passieren, dass ich jemandem ein Buch verliehen habe, den es gar
nicht gibt...)
ORA-02291: integrity constraint (IDROST.EMP_FK) violated - parent key not found
Mitschrift von: Drost, Isabel/ if99wp1
Seite 9 von 23
Einführung in Datenbanken
Semester: IV
Outer emp U Equi U Outer(dept)
Wähle alle enames aus emp und alle dnames aus dept!
Select ename, dname from emp, dept
where dept.deptno=emp.deptno(+)
union
Select ename, dname from emp, dept
where dept.deptno(+)=emp.deptno;
AutoJoin
Suche emp, die mehr als ihr Chef verdienen!
(mgr ist # vom boss)
select e.ename, e.sal, b.ename,b.sal from emp e,emp b
where e.mgr=b.empno
and
e.sal>b.sal
Läuft mit einem Join einer Tabelle auf sich selber.
TetaJoin
Θ
Statt „=“ wird <;>; ... verwendet.
1.
Suche emp, die mehr als Johns verdienen!
select e.ename, e.sal, j.ename, j.sal from emp e, emp j
where e.sal>j.sal
and j.ename='JONES'
BETWEEN – Operator
Suche ename mit Gehaltsklasse!
Das Karthesische Produkt
Wir haben Ziffern von 0-9 und wollen nun alle Dezimalzahlen. Lösung: Verwendung
des krathesischen Produktes, angewendet auf eine Tabelle mit den 10 Dezimalzahlen
von 0 bis 9.
Verwende zur
Programmierung von
Interfaces zu SQL/ Oracle
am besten Java – noch am
meisten unterstützt!
CREATE TABLE digit (d NUMBER);
INSERT INTO digit VALUES (0);
...
INSERT INTO digit VALUES (9);
SELECT e.d +10*z.d FROM digit e, digit z;
Mitschrift von: Drost, Isabel/ if99wp1
Seite 10 von 23
Einführung in Datenbanken
Semester: IV
Subquery
SELECT *FROM emp WHERE sal>(SELECT sal FROM emp WHERE ename='JONES');
Mainquery
Subqurery
Wähle all die aus, bei denen das Gehalt größer ist, als das von Jones. Das von Jones wird dabei in der Subquery
erst ermittelt.
SELECT *FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp);
Wähle die Abteilung, die keine Beschäftigten hat.
SELECT d.dname, e.ename
FROM emp e, dept d
WHERE e.deptno=d.deptno
UNION
SELECT d.dname, NULL FROM dept d
WHERE d.deptno NOT IN (SELECT deptno FROM emp)
Typische Subquery Fehlermeldung:
SELECT *FROM emp WHERE sal>(SELECT sal FROM emp WHERE deptno=30);
Hat zur Folge:
ORA-01427: single-row subquery returns more than one row
SELECT *FROM emp WHERE sal>ANY(SELECT sal FROM emp WHERE deptno=30);
(nimm einen x-beliebigen aus department 30, dabei kommen auch einige aus department 30 mit)
SELECT *FROM emp WHERE sal>ALL(SELECT sal FROM emp WHERE deptno=30);
(nimm die, die mehr verdienen als ALLE in department 30)
•
Statt dem ALL könnte man auch angeben:
•
Anstelle von Any könnte man auch
das Minimum raussuchen:
(SELECT MAX(sal) FROM emp WHERE deptno=30);
(SELECT MIN(sal) FROM emp WHERE deptno=30);
SELECT ename, job, deptno FROM emp WHERE job IN
(SELECT job FROM emp WHERE deptno=30);
Wählt all die jobs mit departmentnumber aus, die in department 30 vorkommen.
SELECT job, deptno FROM emp WHERE job NOT IN
(SELECT job FROM emp WHERE deptno=30)
Wählt all die jobs, die nicht in department 30 vorkommen.
•
•
•
IN
NOT IN
NOT IN
= ANY
!= ALL
= NOT ANY
Mitschrift von: Drost, Isabel/ if99wp1
Seite 11 von 23
Einführung in Datenbanken
Semester: IV
EXITSTS
SELECT *FROM dept WHERE
EXISTS (SELECT *FROM emp WHERE dept.deptno=emp.deptno)
Gib alle Departments aus, zu denen auch ein employee <spc?> gehört.
Exists vergleichbar mit dem „es gibt“ aus der Logik. „Für alle gilt“ lässt sich folgendermaßen darstellen: „Es
gibt keinen, für den es nicht gilt“.
FOR ALL-Ersatz
SELECT dname FROM dept WHERE EXISTS
(SELECT *FROM emp
WHERE emp.deptno=dept.deptno
AND NOT EXISTS
(SELECT *FROM emp
WHERE comm>sal
AND
dept.deptno=emp.deptno
))
Suche Depts, in denen niemand mehr comm als sal erhält!
Suche alle departments raus, bei denen es
folgendes gibt:
Es GIBT Angestellte
Es gibt KEINE Angestellte, die
mehr comm haben als sal haben.
Wir betrachten nur das gewählte Departement,
nicht die ganze Firma.
Wir müssen das so verdreht machen, da es kein „Es gilt für alle“ gibt. Eine Negierung ergibt somit: Es gibt
niemanden, für den das Gegenteil gilt.
SELECT dname FROM dept WHERE EXISTS
(SELECT *FROM emp
WHERE emp.deptno=dept.deptno
AND NOT EXISTS
(SELECT *FROM emp
WHERE hiredate>=TO_DATE('01-JAN-1982','DD-MON-YYYY')
AND
dept.deptno=emp.deptno
))
Suche Depts, deren emps alle vor 82 eingestellt wurden. (Beziehungsweise all die Depts, deren emps NICHT
nach ‘82 eingestellt wurden.)
SELECT dname FROM dept WHERE EXISTS
(SELECT *FROM emp
WHERE emp.deptno=dept.deptno)
MINUS
SELECT dname FROM dept WHERE EXISTS
(SELECT *FROM emp
WHERE hiredate>=TO_DATE('01-JAN-1982','DD-MON-YYYY')
AND
dept.deptno=emp.deptno
)
Das gleiche mit Mengenlehre... (Alle die Zeilen, die emps enthalten, minus die Zeilen, wo das Einstellungsdatum
nicht stimmt.)
Mehrfach SQ
SELECT ename FROM emp
WHERE (sal,job)=
(SELECT sal,job FROM emp WHERE ename='FORD')
All die, die mit dem gleichen Job das gleiche verdienen wie Ford.
Mitschrift von: Drost, Isabel/ if99wp1
Seite 12 von 23
Einführung in Datenbanken
Semester: IV
SQs und Mengen
SELECT ename FROM emp
WHERE job=(SELECT job FROM emp WHERE ename='JONES')
OR
sal>(SELECT sal FROM emp WHERE ename='FORD')
Job(Jones)
Sal(Ford)
SELECT ename FROM emp
WHERE job=(SELECT job FROM emp WHERE ename='JONES')
UNION
SELECT ename FROM emp
WHERE sal>(SELECT sal FROM emp WHERE ename='FORD')
Alle die, die entweder den gleichen job oder das gleiche Gehalt wie Jones bzw. Ford haben.
SELECT * FROM emp
WHERE job
IN
(SELECT job FROM emp
WHERE deptno=(SELECT deptno FROM dept WHERE dname='SALES'))
Alle die, die einen Job haben, der auch im Salesdepartment vorkommt.
SQs und Joins
SELECT *FROM emp, dept
WHERE emp.deptno=dept.deptno
AND
loc='CHICAGO'
AND
job=
(SELECT job FROM emp
WHERE ename='ALLEN')
Loc(CHICAGO)
UND
Join
SELECT *FROM emp, dept
WHERE emp.deptno=dept.deptno
AND
loc='CHICAGO'
Job(ALLEN)
SQ
AND
job=( SELECT job FROM emp WHERE
ename='ALLEN')
Join, der komplett mit einer SQ austauschbar ist: Semijoin. (Da ja die Zeilen der SQ nicht angezeigt sondern nur
ausgewertet werden können...
Mitschrift von: Drost, Isabel/ if99wp1
Seite 13 von 23
Einführung in Datenbanken
Semester: IV
Rekursive SQs
SELECT dname, ename, job FROM dept,
hole aus dept und der temporären Tabelle best. Sachen raus
(SELECT ename, job, deptno FROM emp
die temporäre Tabelle aus dem Select heraus
WHERE TO_CHAR (hiredate,'yy')>'81') emp_v
WHERE dept.deptno=emp_v.deptno ;
Wann kann eine SQ durch einen Join ersetzt werden?
Select *From emp
Where sal>
(Select sal From emp
Where ename='JONES')
Select e.* From emp e, emp r
Where e.sal>r.sal
And r.ename='JONES'
Semijoins lassen sich als SQs darstellen. Joins sind i.d.R. mächtiger als SQs. Somit dürften sich alle SQs als Join
darstellen lassen – als Semijoin. Tlw. lassen sich SQ schneller erstellen als Joins.
Ausdrücke und Funktionen
Select ename, sal+comm From emp Where job='SALESPERSON';
Where sal>comm*0,25
Order by Comm/sal
Sowohl in Selects als auch in WhereKlauseln und OrderByKlauseln sind mathematische Ausdrücke möglich.
Probleme gibt es nur, wenn in einem Summanden NULL drin steht. Lösung ist die NVL Funktion. Bei
NUMBER gibt es dabei kein Problem. Bei allen anderen Datentypen muß ich direkt den Datentyp angeben:
NVL(TO_CHAR ‚nix da‘)
Select ename, sal, comm, sal+NVL(comm,0)
From emp;
Wenn in comm ein nullValue steht, schreibe dafür die
richtige – mathemat. Null und addiere die!
Select ename, sal, NVL(TO_CHAR(comm),'nix da')
From emp;
Diverse Joins in einem Select:
SELECT i.OrdID, i.ItemID, i.ActualPrice, pr.StdPrice FROM Ord o, Item i, Product p, Price pr
WHERE i.OrdID=o.OrdID
AND
i.ProdID=p.ProdID
AND
p.ProdID=pr.ProdID
AND
orderdate BETWEEN pr.startdate
AND
NVL(enddate,SYSDATE)
OrdID
ItemID
ActualPrice
StdPrice
Item
Product
OrdID
ProdID
ActualPrice
ProdID
Ord
Price
OrdID
Mitschrift von: Drost, Isabel/ if99wp1
ProdID
StdPrice
Startdate
Enddate
Seite 14 von 23
Einführung in Datenbanken
Semester: IV
Arithmetik
ROUND
TRUNC
POWER (Basis, Exponent)
SQRT
SIN
etc.
Berechnungen mit der Tabelle dual ausführen. (Tabelle mit nur einer Zeile.)
StringOperationen
CharakterStrings:
SELECT CHR(100) ...
SELECT ASCII(‚d‘)...
Konktination:
SELECT ename||‘is a‘||job...
Decode:
select job, Decode(job,'PRESIDENT',5,'CLERK',1,'MANAGER',3,2) class From emp
Update mittels Decode:
Update emp
set sal=sal*
decode(deptno,10,1.1,
20,1.05,
30,1)
Dies ließe sich auch mit zwei Updates machen. So isses schlicht kürzer.
Substrings:
select substr(dname,2,5) from dept;
Upper und Lower:
Select ename, UPPER(ename), Lower(ename) From emp
Where Lower(ename)=Lower('Scott');
Intr:
Select instr(job,'Person') from emp;
(Soundsooft kommt der angegebene String in dem anderen string vor.)
Initcap:
Select initcap(ename||'is a'||job) from emp;
Erster Buchstabe jedes Wortes wird grossgeschrieben, alle anderen klein.
Mitschrift von: Drost, Isabel/ if99wp1
Seite 15 von 23
Einführung in Datenbanken
Semester: IV
Dump:
Gibt die interne Darstellung des Datums aus:
Typ=12 Len=7: 119,181,11,17,1,1,1
Typ=12 Len=7: 119,181,4,2,1,1,1
Typ=12 Len=7: 119,181,5,1,1,1,1
Typ=12 Len=7: 119,181,6,9,1,1,1
.
.
.
SoundEX:
Ich weiß, wie’s klingt, nur mit der Rechtschreibung habsch so meine Probleme...
SELECT ename, Soundex(ename)
from emp
where soundex(ename)=soundex('Smyth');
Bringt den enthaltenen Smith. (genauso bei Schmied, Schmitt etc.) Der SoundexWert liegt bei S530.
Formatierung von Spalten
Lpad/ Rpad
Column x Heading
‚Histogramm | 0 ... 1000 ... 200 ... 5000‘
Column x Format A50
Justify c
Select ename, sal, LPAD(' ',ROUND(sal/100),'$') x
From emp
;
Select job, LTRIM(job, 'SALE')
From emp
;
alle Zeichen da drin, werden von links beginnend weggeschnitten, die in den
Hochkommas stehen, kommt ein unbekanntes, wird die Ersetzung
abgebrochen
Date:
select hiredate, TO_CHAR(
hiredate,'DAY.MONTH.DD')
from emp
gibt Tag und Monat in Worten aus
select hiredate, TO_CHAR(
hiredate,'"The"ddspth "Day of" MONTH, "The Year of Our Lord" YYYY AD')
from emp
ergibt:
HIREDATE
TO_CHAR(HIREDATE,'"THE"DDSPTH"DAYOF"MONTH,"THEYEAROFOURLORD"YYYYAD'
-------- ------------------------------------------------------------------17.11.81 Theseventeenth Day of NOVEMBER , The Year of Our Lord 1981 N.CHR.
02.04.81 Thesecond Day of APRIL , The Year of Our Lord 1981 N.CHR.
01.05.81 Thefirst Day of MAI
, The Year of Our Lord 1981 N.CHR.
09.06.81 Theninth Day of JUNI , The Year of Our Lord 1981 N.CHR.
20.02.81 Thetwentieth Day of FEBRUAR , The Year of Our Lord 1981 N.CHR.
Mitschrift von: Drost, Isabel/ if99wp1
Seite 16 von 23
Einführung in Datenbanken
Semester: IV
Zeitformatierung:
SELECT TO_CHAR(
SYSDATE,'HH:MI:SS')
FROM dual
Zeitformat lässt sich permanent auch am Server, am Client und in der
Session ändern. Sessionbeispiel (einzig für uns Studis mögliche
Variante):
Ergibt:
TO_CHAR(
-------10:22:59
ALTER SESSION set nls_date_format='"Today''s date is" dd/mm/yy'
;
Ergibt als Formatierung:
SYSDATE
-----------------------Today's date is 08/05/01
Rechnen mit dem Datum ist ebenfalls möglich:
SELECT NEXT_DAY(SYSDATE,'SONNTAG') FROM dual; Sucht den nächsten Sonntag raus
Ergibt: Today's date is 13/05/01 (und heute is der 8.5.2001 – he nur noch ... Select (25-8) from dual
; ... 17 Tage ... bis zum 25 ... *freu*)
SELECT LEAST('21-JAN-77','21-DEZ-77') FROM dual;
Sollte das Kleinere von beiden raussuchen
Ergibt aber den Dezember. Erfolgt deshalb, weil das ganze als String betrachtet wird und das D nunmal vor dem
J im Alphabet kommt... Um es als Datum zu betrachten fehlt die (blaue) To_Date-Funktion.
SELECT LEAST(TO_DATE('21-JAN-77','DD-MON-YY'),TO_DATE('21-DEZ-77','DD-MON-YY')) FROM dual;
SELECT TO_DATE('25-MAI-2001','DD-MON-YYYY')-SYSDATE
from dual;
Hee – noch genau 16,553426 Tage, bis ich Thilo wiedersehe...
Statistikfunktionen von Oracle:
MIN(SAL) SUM(SAL) AVG(COMM)
-----------------------1300
8750
SELECT MIN(sal), SUM(sal),AVG(comm)
From emp
where deptno=10;
Suche den emp mit dem maximalen Gehalt heraus!
SELECT ename,sal from emp
where sal=(Select Max(sal) from emp);
ENAME SAL
---------- --------KING 5000
Wieviel Leute sind in Departement 30?
SELECT COUNT(ename)
From emp
Where deptno=30
Ergibt 6. Nimm keine Spalte, die
Nullwerte enthält, es sei denn
natürlich, du willst die Nullwerte
zählen.
Wieviele verschieden Jobs gibt es in der Firma?
Select count(distinct job) from emp;
Select ename, Max(sal)
from emp
Group by ename
SELECT MAX(sal), COUNT(ename), deptno
FROM emp
GROUP BY deptno;
Mitschrift von: Drost, Isabel/ if99wp1
Damit is zwar der Fehler von ohne wech, dennoch kriege ich
logischerweise nicht das Maximale Gehalt der Firma.
Ergibt pro Abteilung die Mitarbeiteranzahl und das
maximale Gehalt davon.
Seite 17 von 23
Einführung in Datenbanken
Semester: IV
SELECT MAX(sal), COUNT(ename),job, deptno
FROM emp
GROUP BY job, deptno
DEPTNO
--------10
10
10
10
20
20
20
30
30
30
SELECT dept.deptno, dname, job, max(sal)
FROM emp, dept
WHERE dept.deptno=emp.deptno
GROUP BY dept.deptno, dname, job
Maximales Gehalt pro Department, pro Job
SELECT max(sal), job
from emp
group by job
having count(*)>1;
Reihenfolge im GroupBy wirkt sich nur auf die
Ausgabereihenfolge aus, nicht auf’s Ergebnis. GroubBy wirkt
dabei wie ein aufsteigendes OrderBy.
DNAME
-------------- ---ACCOUNTING
ACCOUNTING
ACCOUNTING
ACCOUNTING
RESEARCH
RESEARCH
RESEARCH
SALES
SALES
SALES
MAX(SAL)
--------1300
2450
5000
ANALYST
CLERK
MANAGER
CLERK
MANAGER
SALESPERSON
3000
1100
2975
950
2850
1600
MAX(SAL)
--------- ----3000
1300
2975
1600
Nimm Dir das maximale Gehalt vor,
berechne es pro Jobgruppe und gib es
nur von den Gruppen aus, die mehr
als einen beinhalten, der diesen Job
hat.
SELECT dept.deptno, dname, avg(NVL(sal,0))
FROM emp, dept
WHERE dept.deptno=emp.deptno(+)
GROUP BY dept.deptno, dname
;
JOB
------CLERK
MANAGER
PRESIDENT
JOB
-----ANALYST
CLERK
MANAGER
SALESPERSON
Gib dname, department und
DEPTNO DNAME
AVG(NVL(SAL,0))
AVG(sal) aus. Nimm auch
------ ---------- --------------Operators mit und gib deren
10 ACCOUNTING 2916,6667
20 RESEARCH
2175
sal mit „0“ aus!
30 SALES
1566,6667
40 OPERATIONS 0
Tabellen in Bäume wandeln
SELECT LEVEL, ename, empno,mgr
FROM emp
CONNECT BY mgr=PRIOR empno
START WITH ename='KING'
;
Erstelle eine Rangliste der
Firma, aus der Du einen Baum
konstruieren kannst!
SELECT LPAD(' ',(LEVEL-1)*3)||ename
FROM emp
CONNECT BY mgr=PRIOR empno
START WITH ename='KING'
;
Rücke zusätzlich ein!
SELECT LPAD(' ',(LEVEL-1)*3)||ename
FROM emp
CONNECT BY empno=PRIOR mgr
START WITH ename='SMITH'
;
Wer steht über Smith?
Mitschrift von: Drost, Isabel/ if99wp1
1
2
3
4
3
4
2
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
7839
7566
7788
7876
7902
7369
7698
7839
7566
7788
7566
7902
7839
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
SMITH
FORD
JONES
KING
Seite 18 von 23
Einführung in Datenbanken
Semester: IV
Reihenfolge bei einem zusätzlichen Where:
From
Where
Connect
Start
Order
SELECT LPAD(' ',(LEVEL-1)*3)||ename
FROM emp
WHERE ename!='SCOTT'
CONNECT BY mgr=PRIOR empno
START WITH ename='KING'
Suche die
Reihenfolge raus,
lasse Smith raus.
Dabei baut Oracle
erst die gesamte
Tabelle auf, dann
nimmt es Smith raus
– sonst gängen ja die
drunter verloren.
KING
JONES
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
select prodid, startdate, enddate from price
where prodid=100861;
Nimmt Zeilen raus, in denen die ProduktID nicht mit dem hier übereinstimmt. Haken ist, wenn ich wirklich nur
die Hierarchie dieses Produkte betrachten will, wie hier. Um diese Unterzweige zu erschlagen, muß ich entweder
eine neue Pseudotabelle, View oder rekursive SQ verwenden:
SELECT prodid FROM
(SELECT prodid, startdate, enddate from price where prodid=100861)
CONNECT BY startdate=PRIOR enddate+1
START WITH startdate=TO_DATE('01.01.1985','DD,MM,YYYY')
Zweite Möglichkeit:
Select ...
Connect by ...
AND ename!=‘JONES‘
Wirft auch alle Unterbäume von Jones mit weg.
Select ename,level from emp
where level=2
connect by mgr=prior empno
start with ename='KING'
Select level, AVG(sal) from emp
connect by mgr=prior empno
start with ename='KING'
group by level;
Suche die Abteilungsleiter – die auf
Level 2 – heraus!
Gib pro Level das durchschnittliche
Gehalt aus!
Join mit Connect By etc is nich soo einfach: zum Join gehört eine JoinBedinung und die steht in der
WhereKlausel, die wiederum zuletzt drankommt. Also muß ich den Join wie oben wieder in einer SQ verpacken!
Select level, ename, job from emp
connect by mgr=prior empno
start with empno IN
(Select empno from emp
where job='MANAGER')
;
Mitschrift von: Drost, Isabel/ if99wp1
Baue die Tabelle vom zweiten
Level aus auf – also ab den
Managern!
Seite 19 von 23
Einführung in Datenbanken
Semester: IV
DELETE emp
where empno IN
(Select empno from emp
connect by mgr=PRIOR empno
start with ename='JONES');
Lösche Jones und seine Mannen!
Debugging
Zum Beispiel: gib die Rabatte aus, die die Mitarbeiter gegeben haben
ename – avg/ max/ (StdPrice-ActualPrice)
Debugging in der Datenbänkerei besteht z.B. darin, Daten zu finden, die semantisch inkorrekt sind.
Bezogen auf das Beispiel heißt das:
OrdID – ItemID – stdprice-actualprice, um zu testen, dass jeweils actualprice unter dem stdprice sind. Dabei
muß ich soviele Zeilen erwarten, wie Items (bestellte Artikel) da sind =>64.
Dies ist auf Fehler in den Tabellen zurückzuführen, z.B. gibt es Produkte, die unter dem Minimalpreis oder über
dem Standardpreis verkauft worden sind. Die eine Zeile, die unter den Tisch fällt liegt daran, dass die Bestellung
am 1.5.86 verkauft wurde, der Preis aber erst ab Mitte Mai feststand.
Select dazu:
select itemid, prodid from item
minus
(
select itemid, item.prodid from item, price, ord
where
item.prodid=price.prodid
and item.ordid=ord.ordid
and orderdate between price.startdate and NVL(enddate,sysdate)
)
(ergibt die Zeile, die mir fehlt, in Item bekomme ich jetzt über die prodid und die itemid die richtige ordid heraus
sowie das Datum, ab dem ein Preis feststand. In Ord bekomme ich über die Ordid heraus, dass die Bestellung
abgewickelt wurde, bevor der Preis feststand.
> select *from item where prodid=200376;
ORDID ITEMID PRODID ACTUALPRICE
------ --------- --------- ----------- --------- --------601
1 200376
2,4
1
2,4
613
4 200376
2,2
200
440
620
2 200376
2,4 1000
2400
616
5 200376
2,4
10
24
619
2 200376
2,4
100
240
617
9 200376
2,4
200
480
QTY ITEMTOT
ows selected.
> select *from price where prodid=200376;
PRODID STDPRICE MINPRICE STARTDAT ENDDATE
------ --------- --------- -------- -------200376
2,4
1,75 15.11.86
> select *from ord where ordid=601;
ORDID ORDERDAT C CUSTID SHIPDATE
------ -------- - --------- -------- --------Mitschrift von: Drost, Isabel/ if99wp1
TOTAL
Seite 20 von 23
Einführung in Datenbanken
Semester: IV
601 01.05.86 A
106 30.05.86
2,4
Dies läßt vermuten, dass in den Tabellen noch weitere Fehler sind. Z.B., dass teils der bezahlte Preis über dem
Standardpreis liegt.
SQL> r
STDPRICE MINPRICE ACTUALPRICE
--------- --------- ----------1 select stdprice, minprice, actualprice from price, item, ord
35
28
44
2 where
item.prodid=price.prodid
35
28
56
3 and ord.ordid=item.ordid
45
36
45,11
2,8
2,4
45
4 and orderdate between startdate and Nvl(enddate, sysdate)
5* and stdprice<actualprice
Oder der bezahlte unter dem minimalpreis:
SQL> r
1 select stdprice, minprice, actualprice from price, item, ord
2 where
item.prodid=price.prodid
3 and ord.ordid=item.ordid
4 and orderdate between startdate and Nvl(enddate, sysdate)
5* and actualprice<minprice
STDPRICE MINPRICE
ACTUALPRICE
--------- --------- ----------12,5
9,4
9
45
36
35
Reports
monatliche Ausgaben – packe monatliche Selects in ein Script.
Verwendung von Column möglich:
column Column-name Heading ‚employee|Name‘ format A50;
column column-name off; schaltet die Formatierung wieder aus
column column-name on; schaltet die Formatierung wieder an
column; gibt alle definierten Spalten aus
Weitere Formate (bei Zahlen):
999.99 – runde auf nachkommastellen
999V99 – verstecke den Dezimalpunkt
9,999
B999 – macht aus einer Null ein Blank
09999 – führende Null mit ausgeben
999M1 – Minus am Ende ausgeben
Dies finde ich auch in der SQL+ - Referenz im Netz!
SQL> select deptno, ename, sal from emp order by deptno;
DEPTNO ENAME
SAL
--------- ---------- --------10 KING
5000
CLARK
2450
MILLER
1300
20 JONES
FORD
ADAMS
SCOTT
SMITH
2975
3000
1100
3000
800
30 BLAKE
JAMES
TURNER
ALLEN
WARD
2850
950
1500
1600
1250
Mitschrift von: Drost, Isabel/ if99wp1
Nützlich ist das break:
break on deptno skip 2;
(zeigt dep 10 etc. einmal an, dann
wird sie unterdrückt) Zwischen die
Ausgaben kommen immer zwei
Leerzeilen:
Seite 21 von 23
Einführung in Datenbanken
Semester: IV
break on dname skip 0 on loc skip 0 on deptno;
SQL> r
1 select dname, loc, ename, dept.deptno from
dept,emp
2 where dept.deptno=emp.deptno
3* order by dname
DNAME
LOC
ENAME
DEPTNO
-------------- ------------- ---------- --------ACCOUNTING
NEW YORK
KING
10
CLARK
MILLER
RESEARCH
DALLAS
JONES
20
FORD
ADAMS
SCOTT
SMITH
SALES
CHICAGO
BLAKE
30
JAMES
TURNER
ALLEN
WARD
MARTIN
clear break schmeißt die breaks weg
Tables erstellen und updaten
Projektnummer|Projektname|Budget
101
alpha
250000
102
beta
103
gamma
create table project
(pno number primary Key,
pname varchar(10),
budget number);
insert into project values
(101,'Alpha',250000);
insert into project values
(102,'Beta',Null);
insert into project (pname, pno)
values ('gamma',103);
update project
set budget=100000
where pno=102;
SQL> r
1* select pno, rownum, rowid from project
PNO
ROWNUM ROWID
--------- --------- -----------------101
1 AAAFl5AACAAAFVJAAA
102
2 AAAFl5AACAAAFVJAAB
103
3 AAAFl5AACAAAFVJAAC
Rownum=Zeilennummer, interessant vor allem,
wenn ich laufende Werte verändern will:
update project
set pno=rownum;
RowId=physikalische Adresse der Zeile
innerhalb von Oracle
update project
set pno=pno+1;
Problem dabei ist, dass es sich hierbei um einen PrimaryKey handelt. Zwischenrein gibt es also
übereinstimmende Schlüsselwerte. Bei rein objektorientierten Ansätzen ist dies überhaupt nicht erlaubt, da darf
ich die Keys nicht verändern. Wenn ich diese Möglichkeit nicht hätte, das so abzuschicken, könnte ich
zwischenzeitlich den Primarykey lahmlegen. Ansonsten,wenn ich weiß, der höchste ist 1000, na dann addiere ich
halt erstmal 1001 und ziehe dann 1000 wieder ab ...
delete löscht Zeilen
drop table project löscht die Tabelle.
Mitschrift von: Drost, Isabel/ if99wp1
Seite 22 von 23
Einführung in Datenbanken
Semester: IV
2.
Select Name, NVL(to_char(Beruf),'nix da'), Gehalt From Mitarb
where NVL(to_char(Beruf),'nix da')=
(Select NVL(to_char(Beruf),'nix da') from Mitarb where Name='Walter')
and Gehalt=(Select Gehalt from Mitarb Where Name='Walter')
3.
Select Pname, Count(Pname) From
(
Select Pname, pr.PNR from Projekt pr, Mitpro mi, Mitarb arb
Where
pr.PNR=mi.pnr
and
mi.mnr=arb.mnr
)
group by Pname
having Count(Pname)>7
4.
Select Name from Mitarb
Where Zimnr=
(Select Zimnr From Mitarb Where Name='Froschmann')
and
Mitarb.Abtnr=
(Select Abtnr From Abteilung Where Abtbez='Rechenzentrum')
5.
select Zimnr, count(zimnr) From Mitarb
Group by Zimnr
having count(zimnr)>2
6.
Select Name, Abteilung.Abtnr, Abtbez, Pnr, Pname Pleiter from Abteilung,
Mitarb, Projekt
Where Abteilung.aleiter=Mitarb.mnr
and Abteilung.aleiter=Projekt.pleiter
7.
Select Name, mnr, aleiter, Abteilung.Abtnr, gehalt, 'A
Abteilung, Mitarb, Projekt
Where Abteilung.aleiter=Mitarb.mnr
Union
Select Name, mnr, aleiter, Abteilung.Abtnr, gehalt, 'P
Abteilung, Mitarb, Projekt
Where Mitarb.mnr=Projekt.pleiter
Minus
Select Name, mnr, aleiter, Abteilung.Abtnr, gehalt, 'P
Abteilung, Mitarb, Projekt
Where Mitarb.mnr=Projekt.pleiter
and Mitarb.mnr=Abteilung.aleiter
order by name
' "code" from
' "code" from
' "code" from
8.
Select sum(Gehalt) "Gehaltsumme", count(name) "Anz_Mitarbeiter",
avg(Gehalt) "Durchschn_Gehalt"
from Mitarb
where Gehalt<
(Select avg(Gehalt) from Mitarb)
9.
Select Gehalt, name, vorname from Mitarb
where Gehalt>
(Select avg(Gehalt) from Mitarb)
order by name
Mitschrift von: Drost, Isabel/ if99wp1
Seite 23 von 23
Herunterladen