Daten in Spalte einfügen, aber nur, wenn nicht vorhanden

M*I*B

Benutzer
Beiträge
5
Hallo liebe Forengemeinde,

ich bin der Neue und hoffe hier auf etwas Input, da ich gerade wie der Ochs vor'm Berg stehe ^^

Basis: Tabelle mit UID (unique), aID (nicht unique), fName (nicht unique) und ein paar anderen, die aber keine Rolle spielen
UID ist also immer einzigartig, aber nicht fortlaufend
aID kommt mehrfach vor, bezeichnet aber immer einen Block
fName enthält einen Text

Beispiel:

Code:
 1 - 1 - text1
 2 - 1 - test2
 7 - 1 - text3
12 - 2 - text1
15 - 2 - text7
27 - 3 - text2

Ich möchte nun durch alle Zeilen gehen und schauen, ob jeweils in allen aID- Zeilen ein bestimmter Text vorhanden ist. Wenn nicht, möchte ich in aID diesen Text einfügen.

Also irgendwo was einfügen oder ändern bekomme ich ja noch hin. Aber hier müsste ich ja erst mal alle identischen aID- Zeilen einsammeln und nachschauen, ob der Text vorhanden ist. Und genau da scheitere ich.

Ist es vielleicht einfacher, das ganze aus PHP heraus zu machen? Also erst mal alle Texte aus einer aID in ein Array lesen, schauen ob der Text im Array vorhanden ist und wenn nicht, für diese aID den Text einfügen -> weiter zur nächsten aID?!?

Sachdienliche Hinweise sind sehr willkommen...

LG
Micha
 
Werbung:
Sorry aber versteh nur Bahnhof. Was für ein Text? Was ist eine AID Zeile? Ich dachte AID ist eine Spalte?
 
Text in Spalte 3 "fName"
Und ja, aID ist eine Spalte, aber in der Spalte kann ein und die selbe Ziffer/ID in beliebig vielen Zeilen vorkommen. Ich wollte damit zum Ausdruck bringen, das die ID aus aID sich über beliebig viele Zeilen hinziehen kann und Zeilen mit selbiger aID quasi einen Block bilden, in dem dann jeweils in allen Zeilen mit selber aID in der Spalte fName geschaut werden muss, ob ein bestimmter Text vorhanden ist oder nicht.
 
angenommen du hast:

Code:
postgres=# select * from mib;
 id | aid |   t   
----+-----+-------
  1 |   1 | text1
  2 |   1 | text2
  3 |   1 | text3
  4 |   2 | text1
  5 |   2 | text3
  6 |   3 | text1
(6 rows)

und suchst alle aid, für die es KEIN 'text2' gibt:

Code:
postgres=# with foo as (select aid, array_Agg(t) a from mib group by aid) select * from foo where not ( a  @> array['text2']);
 aid |       a       
-----+---------------
   3 | {text1}
   2 | {text1,text3}
(2 rows)

Du muß also für aid in (2,3) je einen Eintrag mit 'text2' erstellen. Wie die id (bei Dir uid) erstellt wird hast Du nicht beschrieben. Eine Lösung wäre via random() was zu erzeugen, oder Du hast da ein GENERATED ALWAYS oder was vergleichbares.

Code:
postgres=# with foo as (select aid, array_Agg(t) a from mib group by aid) insert into mib select (random() * 100)::int + 10,aid,'text2' from foo where not ( a  @> array['text2']);
INSERT 0 2
postgres=# select * from mib;
 id | aid |   t   
----+-----+-------
  1 |   1 | text1
  2 |   1 | text2
  3 |   1 | text3
  4 |   2 | text1
  5 |   2 | text3
  6 |   3 | text1
 98 |   3 | text2
 75 |   2 | text2
(8 rows)
 
Ahh ok... So grob habe ich es verstanden.
Die UID wird automatisch fortlaufend erzeugt. Die Lücken resultieren aus gelöschten Datensätzen aus der Vergangenheit.

Was ich vergessen habe zu erwähnen: MySQL (MariaDB)
Aber ich glaube auch so halbwegs zu verstehen, worauf Du hinaus willst. Ich werde das heute Abend mal versuchen mit einer Testtabelle; am Livesystem wäre das unklug :rolleyes:
 
Da du so abstrakte Beispieldaten hast ist es ein bisschen schwer verständlich, vielleicht gibst du mal ein logisches Beispiel mit fiktiven Daten. Ich verstehe es so das du für alle aID, die keinen Text haben, den Text einfügen möchtest den die selbe aID in den anderen Spalten hat, und nicht komplett neue Zeile einfügen willst.

Das wäre vom Datenmodell her nicht ganz sauber aber ließe sich machen. Man muss natürlich davon ausgehen das aID nicht immer den selben Text hat, dann würde man z.B. den häufigsten Text nehmen. Aber natürlich nur wenn das wirklich Sinn ergibt.
 
... nö, ich muss schon neue Zeilen einfügen incl. UID, aID, fName, ...
Ich nehme alle mit gleicher aID, gehe jede einzelne Zeile davon durch und schaue, ob in der Zeile z.B. "text13" in fName steht.
Finde ich in keiner einzigen Zeile eines aID- Zeilenblock "text13", muss ich eine Zeile mit automatischer UID, identischer aID (da wo ich gerade gesucht habe) und "text13" in fName erzeugen.
 
Also quasi
Code:
INSERT INTO tabelle(UID,aID,fName)
SELECT DISTINCT newid(),t1.aID,'text13'
FROM tabelle t1
WHERE NOT EXISTS (
SELECT 1
FROM tabelle t2
WHERE t2.aID = t1.aID
AND t2.fName = 'text13'
);
Der Code ist nicht besonders toll aber es geht ja, wie ich dich verstanden habe, um eine einmalige Anpassung. Ansonsten würde sich sagen geht das vielleicht auch noch etwas performanter / eleganter.

Nachteilig ist auch das du an zwei Stellen jetzt text13 hard eincodiert hast und natürlich entsprechend anpassen musst, aber ich wüsste sonst nicht wie ich auf text13 aus der DB komme, also quasi per Bedingung. Es sei denn du sagst jeder nur erdenkliche Text der schon in der Tabelle steht soll für jede aID existieren, dann wäre das einfacher, es würden sich aber auch wieder Sinnfragen stellen zu deinem Tabellendesign :)

newid() ist jetzt MSSQL, keine Ahnung wie MySQL das generiert. Ob DISTINCT in dem Zusammenhang mit MySQL funktioniert weiß ich nicht, sonst muss man das nochmal verschachteln.
 
... vielen lieben Dank!
Ich versuche das mal nach MySQL umzumoddeln...

Das "komfortabler" zu machen ist sinnfrei. Die "Schlüsselwörter", fünf an der Zahl, sind für ewig fix und von daher spricht nichts gegen eine Hardcodierung.
Das muss nicht schön oder komfortabel sein, da eh nur ein Workaround für eine Altlast. Wenn das so funktioniert, reicht es vollkommen, wenn ich das als SQL- Datei auf die Platte schmeiße und bei Bedarf händisch ausführen kann...
 
Werbung:
Bezüglich newid(), das kannst du einfach weglassen, wenn du beim INSERT die column für die Id nicht angibst wird automatisch eine erzeugt wenn die Column auto-increment ist
 
Zurück
Oben