SQL

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

SQL
Hey,

vielleicht kann mir ja der ein order andere eine meiner Fragen beantworten.

  1. Wie komm ich den beim Übungsblatt 7 auf die zahlen inklammern bei dr Aufgabe bei dem man die create table befehle machen muss?
    da steht dann zum Beispiel (24) , woher kommt diese Zahl?

  2. ist string im SQL im Varchar?

  3. wie genau muss ich denn das verstehen mit dem constraint? wann muss ich das verwenden?

Ich blick da irgendwie noch nicht so durch. Würd aber doch gern bis zur Klausur das ganze verstehn :wink:

Danke schonmal


1 / 2) varchar(n) hat im Gegensatz zu char(n) keinen festen Speicherbedarf, sondern passt sich seinem Inhalt an. Das n steht dabei für die maximale Größe der Inhalte (beliebiger Zeichensatz). Du kannst dir also mehr oder minder ein beliebige Zahl aussuchen, hauptsache sie ist einigermaßen groß. Strings müssen in SQL nicht immer varchar(n) sein, gibt zB auch einfach nur den Datentyp text.

  1. Constraints sind Bedingungen für deine Datenbank die beim Einfügen und Ändern gelten müssen (nicht beim löschen, richtig??). Du kannst sie (also Primary key und co) entweder direkt nach den Attributen einer Tabelle definieren, zB
ModellNr INT PRIMARY KEY

oder separat. Der Vorteil sie getrennt zu erstellen ist, wenn ich das richtig verstanden habe, dass man sie eventuell füher oder später noch mal bearbeiten kann, weil sie dann einen konkreten Namen haben, zB

CONSTRAINT FlugzeugPK ModellNr PRIMARY KEY

könnte man über FlugzeugPK addressieren.


okay danke, soweit schonmal klar. Gut.

könnte ich beim Übungsblatt 7 auch bei dem create table Teil, wenn es einen zusammengesetzten Primärschlüssel gibt auch einfach hinter beide teile primary key schreiben oder muss man das dann immer unten drunter machen ? also getrennt?


So weit ich weiß dasgt der Standard in dieser Hinsicht, dass du dafür Contstraints verwenden musst.
Es darf nur einen PRIMARY KEY geben. Dieser darf zwar zusammen gesetzt sein, aber einfach zwei Spalten als PRIMARY KEY definieren ist nicht erlaubt.

Die Lösung wäre dann also:

CONSTRAINT myConstraint PRIMARY KEY(att1, att2)

Allgemein ist die Verwendung von Contraints auf mehrere Attribute nicht dasselbe wie Constraints, die man hinter Attribute schreibt.
Beispiel:

CREATE TABLE firma1(
name varchar(100) PRIMARY KEY,
strasse varchar(100),
hausnummer integer,
plz varchar(100),
CONSTRAINT firma_un UNIQUE(strasse, hausnummer, plz)
);

CREATE TABLE firma2(
name varchar(100) PRIMARY KEY,
strasse varchar(100) UNIQUE,
hausnummer integer UNIQUE,
plz varchar(100) UNIQUE
);

Versuch mal der Firma2-Tabelle zwei Firmen in der selben Straße zu geben ;).

Also es ist nicht nur weniger Schreibarbeit sich Constraints zu sparen, sondern es macht manchmal wirklich einen Unterschied. Bei Primary Keys eben den, dass es nur einen Primary Key pro Tabelle geben darf. Da gibt es dann einen Fehler, wenn man sich nicht dran hält.


hi,

ich hab hier ne Aufgabe wo ich komplett andere Sachen rausgekekriegt hab und ich versteh die Musterlösung nicht so…

Erstellen Sie eine Liste aller Kunden und dem zugehörigen Gewinn, den der Kunde uns
gebracht hat. Die Liste ist nach Gewinn absteigend zu sortieren. Gewinn ist bei uns die
Differenz zwischen Verkaufspreis und Einkaufspreis (je Artikel gedacht; für den Kunden
als ganzes kommt die Menge aller Artikel und die jeweilig bestellte Anzahl in die
Verrechnung hinzu). Erstellen Sie zuerst eine View, welche alle Produkte mit
Artikelnummer und Gewinn beinhaltet.

Tabelle:

vorname | nachname | strasse | hausnummer | plz | stadt | gewinn

SELECT vorname
, nachname
, strasse
, hausnummer
, plz
, stadt
, SUM(anzahl * gewinn) AS gewinn
FROM gewinn g
, kunde k
, bestellung b
, bestellung_produkt bp
WHERE k.kreditkartennummer = b.kunde
AND b.id = bp.bestellung
AND bp.artikelnummer = g.artikelnummer
GROUP BY kreditkartennummer –- weil es der PK ist!
– Der Rest kommt in die Projektion:
, vorname
, nachname

Also ich versuch mal zu erklären was mir da alles nicht klar ist.
erstmal wieso steht bei FROM kunde k, bestellung b usw. wieso stehn da buchstaben dahinter? O.o
und was bedeutet das bei dem WHERE? wieso muss das dahin?
und wieso steht bei SELECT nicht (preis-einkaufspreis)*anzahl AS gewinn?

Und kann das ganze auch mit einem JOIN gemacht werden?


[quote=me95zuho]
Also ich versuch mal zu erklären was mir da alles nicht klar ist.
erstmal wieso steht bei FROM kunde k, bestellung b usw. wieso stehn da buchstaben dahinter? O.o
und was bedeutet das bei dem WHERE? wieso muss das dahin?
und wieso steht bei SELECT nicht (preis-einkaufspreis)*anzahl AS gewinn?

Und kann das ganze auch mit einem JOIN gemacht werden?
[/quote]Da “from A, B where ” genau das gleiche bedeutet wie “from A join B on ”, kann man das auch mit einem join machen.
Die Buchstaben beim from sind Abkuerzungen. Wie du z. B. in der ersten where-Zeile siehst, kann man dann k.kreditkartennummer statt kunde.kreditkartennummer schreiben. Ausserdem braucht man das bei einem Autojoin (join einer Tabelle mit sich selbst), um die beiden beteiligten Tabellen auseinanderzuhalten (z.B. FROM tabelle x, tabelle y).
Zur select-Frage: Wahrscheinlich wurde in einer view namens gewinn (s. 1. from-Zeile) gewinn als (preis - einkaufspreis) definiert.


Hey danke für die schnelle antwort.

Ah ja das wurde so definiert. Aber kann man das auch erst im SELECT berechnen? Ja oder?

und noch ne Frage zu dem WHERE:

wieso wird das denn da die Kreditkartennummer nochmal mit dem Kunden und das Produkt nochmal mit der ProduktID abgeglichen?
Also so vom normalen denken is mir das unklar wofür das noch gemacht werden muss?! hmm…
ich hab das Where da ganz weggelassen irgendwie.

Und irgendwie komm ich mit dem Group by nicht klar. für mein verständnis ist das irgendwie immer unnötig da, also irgendwie versteh ich den Sinn vond em nicht so ganz.


Wenn du zwei Tabellen in der from Klausel hast (entweder durch Kommatas getrennt oder mit join und co. verbunden), dann entsteht in der Regel das Kreuzprodukt, d.h. jedes Tupel aus jeder Tabelle wird mit jedem anderem Tupel konkateniert. Das ist erst mal ein riesen Batzen, von dem dich aber nur ein Bruchteil interessiert. Daher die Auswahl Kriterien im where, damit auch nur die Tupel-Kombinationen rauskommen, die einen ‚Sinn‘ ergeben (die zueinander gehören).

Das Attribut Kunde von bestellung ist ein Fremdschlüssel auf den Primärschlüssel von der Tabelle kunde (hier kreditkartennummer). Um die beiden Tabellen sinnvoll miteinander zu verbinden. also alle Bestelleungen die einem Kunde gehören zu ermitteln, muss man das Kreuzprodukt einschränken. Daher der Vergleich.


Ich glaube, es wurde schon einmal hier irgendwo gefragt, aber ich konnte es nicht mehr finden:

In der Musterlösung zu Blatt 08 steht:
[…]
SELECT
firma.strasse AS strasse,
firma.plz AS plz,
[…]

Muss ich wirklich jedes Mal ein AS dahinter setzen, wenn ich den namen ja eigentlich nicht verändere?


Ja weil im Standard heißen deine Spalten sonst echt „firma.plz“ „firma.strasse“.
Mach es einfach, sind nur 2 Wörter pro Attribut.

/edit

und wenn du die angelegten Tables/Views später wieder gebrauchen willst weiß ich nicht ob es möglich ist auf die Attribute noch problemlos zuzugreifen:

create view blub as
select k.name, k.umsatz
[…]

select b.k.name (<-- ?! keine Ahnung ob soetwas überhaupt geht)
from blub b
where […]


Okay, danke :wink:


Geht es nicht theoretisch auch einfach das “firma.” wegzulassen, wenn man nicht grad nen autojoin hat.
Dann kann man sich das umbenennen auch sparen.
Man sollte sich aber halt immer überlegen ob der Attributname wirklich eindeutig ist (bei nem natural join ist das z.b. immer der fall glaube ich).


Jaein:

Angenommen du hast 2 Relationen

Bestellung(Bestellnummer, Artikelnummer, Kundenummer, Name) und Kunde(Name, Bestellnummer, Adresse)

Dann könntest du machen:

select *
from Bestellung b join Kunde k using (Bestellnummer)
[…]

Jetzt sieht die Ergebnisrelation aber so aus:

Bestellung_Kunde(Bestellnummer, Artikelnummer, Kundenummer, Name, Name, Adresse)

und wenn du den Namen selecten willst bräuchest du aber wieder k.name oder b.name

/sry ein besseres Beispiel ist mir nicht eingefallen


hey, ich versteh das GRUP BY nicht.

Wieso braucht man das hier?

Wir benötigen zu allen Bestellungen-IDs die Anzahl der zugehörigen Pakete, die
verschickt wurden. Sortieren Sie das Ergebnis absteigend nach der Paketanzahl.

SELECT bestellung
, COUNT(*) AS anzahlpakete
FROM paket
GROUP BY bestellung
ORDER BY anzahlpakete DESC;


Du gruppierst nach der Bestellung-ID, d.h. du hast x verschiedene Gruppen, eine für jede ID (das macht group by). Mittels count(*) kann man die Anzahl der Elemente in einer Gruppe zählen, hier also die Anzahl der Pakete pro Bestellung-ID.

Reicht das? :wink:


Also ich glaub mein problem wird nicht richtig klar. Ich versuchs nochmal.

zum einen verstehe ich nicht wieso man da FROM Paket geht und die BestellID steht ja unter Bestellung und nicht unter Paket.
Das Count habe ich glaube ich schon bestanden, aber was bedeutet “du gruppierst nach der Bestellung-ID”? Was würde denn passieren ohne das Group By? Ich hab einfach immer das Problem, dass ich nicht erkenne, wann ich GROUP BY brauche und wann nicht.

danke für deine mühe :slight_smile:


So wie ich das sehe, würdest du ohne das GROUP BY die Anzahl aller Bestellungen bekommen.


Alle Informationen die du brauchst sind in der Tabelle Paket, desshalb auch kein join. Die Bestellung_ID versteckt sich unter bestellung[bestellung] (ist ein Fremdschlüssel auf den Primärschlüssel von der Tabelle Bestellung).

Wenn man jetzt auf diese Relation group by bestellung (also der bestellungs_id) macht, dann enstehen verschiedene (auch wenns rein formal nicht richtig ist, macht die Sache aber vielleicht ein bisschen anschaulicher) Untertabellen, eine pro ID.

Ohne group by hast du diese Unterteilung nicht und count(*) würde die nur die gesammt Anzahl von Tupeln liefern, nicht aber pro ID … das was Nyx sagt :wink:


endlich endlich endlich yuhu!

Ich dachte schon cih werde es niiemals verstehn!

Danke euch beiden!!