Ich habe eine Tabelle (test) mit 15 verschiedenen Spalten und darin enthaltenen Daten, alle VARCHAR(255) bis auf die Spalte ID_Druck (integer)
Die Abfrage soll mir den Ersten, letzten und jeden 5000sten Datensatz duplizieren und in das Duplikat in die Spalte “BELEGE” einen beliebigen Textwert (hier Belege) eintragen
Meine Abfrage funktioniert soweit gut mit dem Duplizieren der Spalten, jedoch bekomme ich es einfach nicht hin, dass nur in die Duplizierten Spalten ‘Belege’ eingetragen wird.
Als Server benutze ich PostgreSQL Vesion 9.1.1-1
Vielleicht kann mir hierbei jemand helfen
Die Abfrage sieht folgendermaßen aus:
WITH belege AS ([INDENT]SELECT * FROM test WHERE “ID_Druck” = 1[/INDENT]
[INDENT]UNION ALL[/INDENT]
[INDENT]SELECT * FROM test WHERE 0 = round(mod(“ID_Druck”,5000))[/INDENT]
[INDENT]UNION ALL[/INDENT]
[INDENT]SELECT * FROM test WHERE “ID_Druck” = (SELECT max(“ID_Druck”) FROM test)
),[/INDENT]
belegein AS ([INDENT]UPDATE test SET “BELEGE” = ‘Beleg’[/INDENT]
[INDENT])[/INDENT]
INSERT INTO test SELECT * FROM belege, belegein
test=# select * from truehumandesign;
id | c | t
----+-------+---
1 | eins |
2 | zwei |
3 | frei |
4 | vier |
5 | fuenf |
(5 rows)
test=*# with beleg as (select c, 'NEU' from truehumandesign) insert into truehumandesign (c, t) select * from beleg;
INSERT 0 5
test=*# select * from truehumandesign;
id | c | t
----+-------+-----
1 | eins |
2 | zwei |
3 | frei |
4 | vier |
5 | fuenf |
6 | eins | NEU
7 | zwei | NEU
8 | frei | NEU
9 | vier | NEU
10 | fuenf | NEU
(10 rows)
Vermutlich habe ich die Fragestellung etwas komisch geschrieben.
Hab jetzt aber ne Query hinbekommen die dem ganzen schon eher ähnelt was ich will:
WITH belege AS (UPDATE foo2 SET "BELEGE" = 'Beleg'
WHERE "ID_Druck" = 1
OR "ID_Druck" = (SELECT max("ID_Druck") FROM foo2)
OR 0 = round(mod("ID_Druck",5000))
RETURNING *
)
INSERT INTO foo2 SELECT * FROM belege
Das einzigste woran es jetzt noch hakt ist, dass er Beleg nur in die Duplizierte Spalte kopieren soll und nicht auch in die andere.
Er fügt ja im moment überall wo 1 oder max(ID_Druck) oder jede 5000ste “ID_Druck” Belege ein
Ja ich seh schon das er Alle Spalten die 1 oder max(“ID_Druck”) etc. ein “beleg” einfügt.
Ich hab jedoch keine ahnung wie ich es umschreiben soll, das er nur in die angefügten Beleg einfügt
Vielleicht komme ich ja hiermit auf den richtigen Weg:
WITH belege AS (INSERT INTO foo2 (“BELEGE”) VALUES (‘Beleg’)
WHERE “ID_Druck” = 1
OR “ID_Druck” = (SELECT max(“ID_Druck”) FROM foo2)
OR 0 = round(mod(“ID_Druck”,5000))
RETURNING *
)
INSERT INTO foo2 SELECT * FROM belege
Innerhalb von WITH belege ( … ) machst Du ein Select mit Deiner WHERE-Condition, den Spalten, die übernommen werden sollen und den Werten, die statt der in den Spalten stehenden Werten eingesetzt werden sollen. Das Resultat hängst Du via INSERT an Deine Tabelle. Also, innerhaln von WITH belege ( … ) muß das rausrommen, was Du anhängen willst. Kann doch nicht SOOO schwer sein, oder?
WITH belege AS (
SELECT * FROM foo2
WHERE "ID_Druck" = 1
OR "ID_Druck" = (SELECT max("ID_Druck") FROM foo2)
OR 0 = round(mod("ID_Druck",5000))
)
INSERT INTO foo2 SELECT * FROM belege
Ich weiß nur nicht wie ich ihm in der WITH sagen soll die Belege in die Spalte einzufügen.
Bekomm das mit INSERT TO nicht hin!
Nu meckert Postgre weil ID_Druck type integer ist.
Habs in alle möglichen Zahlentypen umgewandelt, bringt aber nix
********** Fehler **********
FEHLER: Spalte »ID_Druck« hat Typ integer, aber der Ausdruck hat Typ character varying
SQL Status:42804
Hinweis:Sie müssen den Ausdruck umschreiben oder eine Typumwandlung vornehmen.
Mein Code soweit sieht ganz gut aus… ich glaub ich versteh was du meinst Andreas
WITH belege AS (
SELECT "BELEGE", 'Beleg' FROM foo
WHERE "ID_Druck" = 1
OR "ID_Druck" = (SELECT max("ID_Druck") FROM foo)
OR 0 = round(mod("ID_Druck",5000))
)
INSERT INTO foo SELECT * FROM belege;
WITH belege AS (
SELECT "ID_Druck", "LFDNR", 'Beleg' FROM foo
WHERE "ID_Druck" = '1'
OR "ID_Druck" = (SELECT max("ID_Druck") FROM foo)
OR 0 = round(mod("ID_Druck",5000))
)
INSERT INTO foo SELECT * FROM belege;
Wenn ich bedenke wie umständlich die erste Abfrage war
Eins stört mich jedoch.
Da ich öfters mal bis zu 33 Spalten habe will ich nicht immer alle einzeln im SELECT aufführen.
Gibts da keine andere Möglichkeit? Oder eine Andere möglichkeit die Row “BELEGE” mit Belegen zu füllen.
Ich gebe mal eine Geschichte aus dem Alltag bei einem Hosting-Provider wieder:
Kunde hatte auf einer gut besuchten Seite sporadisch Fehlermeldungen. Und zwar konnte MySQL keine temp. Tabellen mehr anlegen. /var/tmp, wo dies erfolgte, war ca. 10 mal größer als die Größe aller MySQL-DBs zusammen.
Es stellte sich raus, daß da sinngemäß folgendes Select die Ursache war:
select einzelne_spalte from (select * from foo) where andere_spalte = N
(das select war komplexer, ließ sich aber darauf reduzieren)
foo war eine Tabelle mit einigen hundertausend Zeien, jede Zeile enthielt Dutzende langer Textfelder, also vielleicht 70 lange Felder. Die einzelne_spalte war ein INT, andere_spalte (Ziel des WHERE) war der PK von foo.
Aufgrund der hirnrissigen select * in der Klammer war MySQL genötigt, die komplette Tabelle als materialisierte temp. Tabelle zu erstellen. Laufzeit der Anfrage entsprechend.
Eigentlich wollte der Kunde das Problem mit Hardware erschlagen, sein Programmiere hätte ihm das vorgeschlagen. Ich hab ihm dann erklärt, was für ein zensiert dieser Programmierer ist.
Anderes Beispiel aus meiner Welt: wir machen “Big Data”, sprich Data Warehousing.
Wenn du dort ein “SELECT *” machst, zwingst du die Datenbank, alle Spalten von der Platten zu lesen.
Im günstigsten Fall hast du pro Spalte eine Datei auf der Festplatte - durch die Angabe der einzelnen Spalten gewinnst du massiv an Performance.
Um akretschmer zu zitieren: niemals nie und nimmer mach ein “SELECT *”.
Ok das versteh ich jetzt endlich mit der Select * From abfrage!
Vielen Dank für die Hilfe!!
Da ich die Abfrage sowieso in ein Python Programm schreibe werde ich alle Spaltennamen über Variablen einfügen (somit ist es weniger Tipparbeit) und die Selektion erfolgt über einen GUI.