SQL-Blog

MariaDB, PostgreSQL, MySQL, … Erfahrungsberichte, Meinungen, …

23. Februar 2015
nach FTH
Keine Kommentare

Sortieren ja, aber ich entscheide wer an der Spitze steht

Stell dir vor, du sollst eine Liste mit MitarbeiterInnen ausgeben, die nach Nachnamen alphabetisch sortiert sein soll. Das ist ja kein Problem, ein ORDER BY nachname würde hier schon reichen. Nur der Chef ist so eitel, dass er natürlich an der Spitze der Liste stehen will.
Dafür zeige ich dir hier eine, oder besser gesagt zwei Lösungen.

Ausgangslage

Wir haben eine unsortierte Tabelle in der die Namen der MitarbeiterInnen gespeichert sind. Der erste Schritt die Namen einfach mit einem

ORDER BY nachname

zu sortieren ist dir vermutlich auch bekannt.

Ausgangsdaten

Ausgangsdaten

Ausgangsdaten sortiert nach Nachname

Ausgangsdaten sortiert nach Nachname

Die Person an der Spitze

Jetzt nehme ich einmal an, dass die Fr. Maria Meier die Chefin ist, die ich an der ersten Stelle der Liste positioniert haben will. Dafür habe ich grundsätzlich 2 Möglichkeiten.

Möglichkeit 1 ORDER BY erweitern

Meine erste Möglichkeit eine Tabelle mit Fr. Meier an erster Stelle und danach alle Personen in alphabetischer Reihenfolge zu bekommen besteht darin, dass ich den ORDER BY Teil in MySQL um ein IF erweitere, in PostgreSQL muss ich dafür ein CASE verwenden:

MySQL / MariaDB

SELECT * FROM testadressen

ORDER BY IF(nachname='Meier',0,1),nachname;

PostgreSQL

SELECT * FROM testadressen

ORDER BY CASE WHEN nachname='Meier' THEN 0

ELSE 1 END, nachname;

In beiden Fällen erzeugen wir eine ‚virtuelle‘ Spalte, die mit ‚0‘ und ‚1‘ befüllt wird und nach der danach sortiert wird und als 2. Suchkriterium gilt nach wie vor unsere Spalte ’nachname‘.

Sortierte Tabelle mit anderer Person an der Spitze

Sortierte Tabelle mit anderer Person an der Spitze

Natürlich kann die Bedingung im IF – Statement noch erweitert werden. Ich habe im Beispiel zwei Personen mit dem Nachnamen Huber und ich möchte die Eva Huber an die erste Stelle bringen, also schreibe ich:

SELECT * FROM testadressen

ORDER BY IF(nachname='Huber' AND vorname='Eva',0,1), nachname;
Erweiterung des IF - Statements

Erweiterung des IF – Statements

2. Möglichkeit die Sortierung von Daten zu beeinflussen

Als 2. Möglichkeit die Sortierung einer Datenbanktabelle zu beeinflussen habe ich noch die Möglichkeit eine eigene Spalte in der Tabelle anzulegen, die einzig und alleine der Sortierung dient.

Eigene Spalte zur Sortierung

Eigene Spalte zur Sortierung

Der Vorteil einer eigenen Spalte zur Sortierung liegt darin, dass ich mir damit beliebige Hierachien zu Sortierung aufbauen kann, die sich auch dann nicht ändern, wenn andere Daten wie z.B. der Name einer Person geändert wird.

7. April 2014
nach FTH
Keine Kommentare

Update – Timestamp in PostgreSQL

Eine oft benötigte Funktion in Datenbankanwendungen ist, dass man in einer Tabelle eine Spalte mitführt, die den letzten Änderungszeitpunkt eines Datensatzes speichert. MySQL bietet uns die Möglichkeit so eine Spalte direkt bei der Tabellendefinition anzulegen, in dem einfach ein Feld des Typs Timestamp mit folgender Eigenschaft: „on update CURRENT_TIMESTAMP" angelegt wird.

In PostgreSQL ist dieser Effekt etwas aufwendiger, aber auch nicht komplizierter zu erreichen. Man benötigt dafür allerdings 2 Schritte. Zum einen muss eine Triggerfunktion angelegt werden und zum anderen muss der Trigger selbst erstellt werden. Es ist zu empfehlen, in allen Tabellen der Datenbank die Spalte für den Timestampwert gleich zu benennen, dann ist die Funktion universell einsetzbar und man muss für jede Tabelle nur noch den Trigger anlegen.

In meinem Beispiel sieht die Funktion die vom Trigger aufgerufen wird folgender Maßen aus, wobei „last_update“ der Name meiner Timestamp – Spalte ist:

CREATE OR REPLACE FUNCTION set_update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.last_update = now();
RETURN NEW;
END;
$$ language 'plpgsql';

Hat man diese Funktion angelegt muss eben noch für jede Tabelle, die dieses Timestamp-Feld enthält folgender Trigger erstellt werden:

CREATE TRIGGER set_last_update BEFORE UPDATE OR INSERT
ON table FOR EACH ROW EXECUTE PROCEDURE
set_update_timestamp();

Also sie sehen es ist auch in PostgeSQL nicht so schwierig den Änderungszeitpunkt eines Datensatzes automatisch zu speichern.

26. November 2013
nach FTH
Keine Kommentare

Datenbanktabelle klonen

Des öfteren kommt man in die Situation, dass man gerne einen 1:1 Kopie einer Datenbanktabelle haben möchte. Sei es um diverse Abfragen und Berechnungen an quasi Echtdaten zu testen, oder man will einfach nur die Tabellenstruktur klonen, usw. Das klonen einer Datenbanktabelle ist mit Hilfe von SQL – Befehlen in fast allen Datenbankmanagementsystemen ein Kinderspiel.

Das einzige was beim Klonen natürlich nicht möglich ist, ist dass die geklonte Tabelle eins zu eins den gleichen Namen bekommt wie die original Tabelle.

Kommen wir nun gleich zu den wichtigsten Befehlen für das Klonen. Ich zeige euch zuerst ein Beispiel in MySQL, bzw. MariaDB und danach in PostgreSQL.

MySQL, bzw. MariaDB

In MySQL reichen 2 Befehlszeilen für das Klonen.

Als erstes erstellen wir eine Kopie der Tabellenstruktur:

CREATE TABLE klon LIKE original;

So einfach bekommen wir eine Tabelle klon, die die selbe Struktur aufweist, wie die Tabelle original.

Jetzt geht es nur noch darum auch die Daten vom Original in den Klon zu kopieren und das erreichen wir mit:

INSERT INTO klon SELECT * FROM original;

Das Kopieren der Daten kann natürlich einiges an Zeit in Anspruch nehmen. Natürlich ist es auch empfehlenswert nach dem Kopieren zu prüfen, ob wohl wirklich alle Daten richtig kopiert wurden.

PostgreSQL

Auch in PostgreSQL ist das Klonen ein Kinderspiel. Wie in MySQL kommt man auch in PostgreSQL mit zwei Zeilen aus, der Befehl zum Kopieren der Daten ist sogar derselbe.

Also das Kopieren der Struktur geht mit:

CREATE TABLE klon (LIKE original INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES );

Wie man hier schön erkennen kann, ist es notwendig etwas genauer anzugeben, was alles in die Struktur der neuen Tabelle mit übernommen werden soll.

Und wie bereits erwähnt geht das Kopieren der Daten analog zu MySQL:

INSERT INTO klon SELECT * FROM original;

Fazit

Es ist ganz einfach ganze Tabellen zu duplizieren, einzig bei großen Datenmengen kann es schon eine Weile dauern, bis die Daten vollständig kopiert sind.

Als Tipp kann ich noch mitgeben, dass es je nach Datenbank sinnvoll sein kann, den Kopiervorgang innerhalb einer Transaktion auszuführen.