mysql Datensätze aus 2. Tabelle prüfen und Werte in 1. Tabelle 1. llere Spalte schreiben

charly127

Grünschnabel
ich habe 2 Tabellen, in Tab1 soll ein Wert (2017) in die erste freie Spalte eingetragen werden, wenn der wert aus tab2 >=10
tab1:
tab1-png.65304

tab2:
tab2.png
 

Anhänge

  • tab1.png
    tab1.png
    8,8 KB · Aufrufe: 21
Hallo,

nur das ich es richtig verstehe. Bei mnr = 2017001 muss in die Spalte s3 2017 eingetragen und bei 2017004 in die Spalte s2 eingetragen werden. Richtig?

Bist du am Design der Datenbanktabellen festgenagelt? So wie diese aktuell ist geht es mit reinem SQL meiner Meinung nach nicht.
 
richtig, so sollte es sein.
das design der tab1 ist so festgelegt, ich habe schon versucht, die Zielspalten einzeln abzufragen (
SELECT * FROM tab1 WHERE s1 = '' OR s1 IS NULL)
das klappt, weiß aber nicht, wie dann nur diese gefüllt werden können, und bei der nächsten Abfrage für s2 müssten dann die Datensätze mit Eintrag s1 unberücksichtigt bleiben.
 
Wie gesagt. Mit reinem SQL wirst du um folgendes Konstrukt nicht herumkommen
SQL:
UPDATE
    tab1
JOIN
    tab2
   ON tab1.mnr =tab2.mnr
SET
    s1='2017'
WHERE
    s1 IS NULL
   OR s1 = ''

Bei diesem Code hast du aber noch keine Validierung, ob für die Zeile in einer anderen Spalte 2017 steht.
 
Aua. Du solltest ganz dringend die Tab1 Normalisieren!
So wird das nix sinnvolles. Auch wenn man es lösen kann. Die Performance geht bachab und du wirst in Zukunft immer wieder Probleme haben.

Ich habe für die Tests nur deine ersten drei Zeilen erfasst. Auch die S-Felder habe ich mal auf drei beschränkt

Zu erst mal zur veranschaung die Normalisierung von tab1
SQL:
select t.mnr, t.s1 as value, 's1' as col
from tab1 t
union all select t.mnr, t.s2 as value, 's2' as col
from tab1 t
union all select t.mnr, t.s3 as value, 's3' as col
from tab1 t
Code:
| mnr    | value | col |
| 201701 | 2014  | s1  |
| 201702 | 2012  | s1  |
| 201703 |  	 | s1  |
| 201701 | 2015  | s2  |
| 201702 |  	 | s2  |
| 201703 |  	 | s2  |
| 201701 |  	 | s3  |
| 201702 |  	 | s3  |
| 201703 |  	 | s3  |

Ok, wir brauchen das jetzt für den Update nicht. Aber du siehst, normalisiert ist besser zum bearbeiten
Dein Update könnte so aussehen
SQL:
update
	tab1 t1, 
	tab2 t2
set
   t1.s1 = ifnull(t1.s1, t2.wert),
   t1.s2 = case 
		when t1.s2 is null and not t1.s1 is null
		then t2.wert
		else t1.s2
	end,
   t1.s3 = case 
		when t1.s3 is null and not t1.s2 is null
		then t2.wert
		else t1.s3
	end
	-- TODO: Weitere Felder analog hinzufügen
where 
	t1.mnr = t2.mnr 
	and t2.wert > 10;
 
Moin Yaslaw,

ist dir nicht die kleine Nebenbedingung "keines der Felder s1, s2, ..., s5 darf schon den Wert 2017 enthalten" durch die Lappen gegangen?

Also nur noch eine Ergänzung der WHERE-Bedingung um
...
AND t1.s1<>'2017'
AND t1.s2<>'2017'
AND t1.s3<>'2017'
...
(falls die Felder wirklich Textfelder sind. Falls Jahr numerisch ist, dann ohne Anführungszeichen.)

Grüße
Biber
 
Oh - stimmt. Und es soll ja nicht der Wert eingetragen werden sondern 2017

Schön ist das nicht
SQL:
UPDATE
    tab1 t1, 
    tab2 t2
SET
    t1.s1 = ifnull(t1.s1, 2017),
    t1.s2 = CASE 
        WHEN t1.s2 IS NULL AND NOT t1.s1 IS NULL
        THEN 2017
        ELSE t1.s2
    END,
    t1.s3 = CASE 
        WHEN t1.s3 IS NULL AND NOT t1.s2 IS NULL
        THEN 2017
        ELSE t1.s3
    END
    -- TODO: Weitere Felder analog hinzufügen
WHERE 
    t1.mnr = t2.mnr 
    AND t2.wert > 10;
    and t1.s1 <> 2017
    and t1.s2 <> 2017
    and t1.s2 <> 2017
    -- TODO: Weitere Felder analog hinzufügen
 
...aber trotz alledem:
eine so verquaste Tabellenstruktur gehört dringend auf dem Prüfstand.

Sollbruchstellen sind:
- wenn jemand hinterher auswerten möchte, welche MNummern denn erwähnt wurden für das Jahr 2017, dann muss genauso dusselig über 5 Felder abgefragt werden (WHERE s1=2017 or S2=2017... or s5=2017). Keinerlei Indexnutzung möglich und deshalb stinkelangsam.

- wenn in der Zieltabelle mal ein Satz für 2017 eingetragen wurde am letzten Donnerstag, weil zu diesem Zeitpunkt der t2.wert > 10 war. dann steht der Satz halt drin. Ändert sich der t2.wert heute auf < 10, wird der Satz aber nicht gelöscht. Den umgekehrten Fall, also eine mnr wäre gerade heute vom Wert 9 auf den Wert 11 gestiegen und käme deshalb neu hinzu, diesen Fall würde das Updatestatement abfackeln.

Aber inkonsisitent und widersprüchlich sind die Daten dennoch, also für die Tonne.

Ich würde vollkommen auf diese versuchte redundante Datenhaltung verzichten und diese Pseudo-Pivottabelle live erzeugen aus den t2-Daten. Dann liegt nach dem Pivotieren ein Resultset vor mit den Feldern Mnr, 2012, 2013, 2014... , 2017 und für jedes vorhandene Jahr ist eben ein ='x' oder 'ja' oder whatever gesetzt.

Grüße
Biber
 
Zurück