Forum: PC-Programmierung MySQL anfänge


von Sebastian (Gast)


Lesenswert?

Hi,

ich versuche gerade etwas MySQL zu lernen.

Ich habe viel gegoggelt, aber ich bekomme es leider nicht hin.
1
Tabelle1
2
 _______________________
3
ID| Wert1 | Wert2 | Wert3|
4
1 |  AB   |   1   | blubb|
5
1 |  AC   |   2   | bla  |
6
1 |  AD   |   3   | egal |
7
1 |  AE   |   4   | bal  |
8
2 |  AB   |   5   | egal |
9
2 |  AC   |   6   | blub |
10
2 |  AD   |   7   | egal |
11
2 |  AE   |   8   | egal |


Vereinfacht ausgedrückt, möchte ich, wenn in Wert1 "AC" steht, dass ich 
das Ergebnis aus Wert2 bekomme. Also in diesem Fall sollte ich für ID 1 
eine 2 zurückbekommen und für ID 2 eine 6.
1
select 
2
ID,
3
CASE WHEN Wert1 = 'AC' THEN 'Wert2'  ELSE 'nicht gefunden' END as Wert1,
4
Wert3
5
6
from Tabelle1
7
WHERE ID IN (1, 2)
8
GROUP BY Wert3;

Wie müsste das korrekt aussehen?

von Peter II (Gast)


Lesenswert?

Sebastian schrieb:
> Wie müsste das korrekt aussehen?

warum das Group, davon steht nichts in deiner "Aufgabe"?

1
select 
2
   ID,
3
   CASE WHEN Wert1 = 'AC' THEN Wert2 ELSE 'nicht gefunden' END as Wert
4
from Tabelle1
5
WHERE ID IN (1, 2)

jetzt gibt es aber noch das Problem das du bei else ein varchar 
zurückgibtst und sonst vermutlich ein int - das kann nicht gtehen.

von Jan B. (do9jhb)


Lesenswert?

Hi,

wenn ich dein Problem richtig verstanden habe, würde ich es grob so 
lösen:
1
SELECT id, wert2 FROM tabelle1 WHERE Wert2='AC'
. Wenn du den Wert nur für eine bestimmte ID haben willst, dann musst du 
noch ein
1
AND id=DEIN_WERT

von Michael B. (laberkopp)


Lesenswert?

Sebastian schrieb:
> Wie müsste das korrekt aussehen?

Deine Vergewaltigung des Spaltenwerts Wert1 ist katastrophal. Du 
bekommst niemals 2 oder 6 raus, sondern nur 'Wert2' oder 'nicht 
gefunden' als String unter dem Namen Wert1.

Kannst du nicht mit dem zufrieden sein, was deine Datenbank liefert ?

Auch ein GROUP BY Wert3 erscheint zumindest bei dieser Anfrage und 
dieser Tabelle grob katastrophal. So durcheinander, daß man sich fragt, 
was du eigentlich willst.

Was gefällt dir an

SELECT * FROM Tabelle1 WHERE Wert1='AC' ORDER BY ID

nicht ?

von hans (Gast)


Lesenswert?

also mit mehrfach "gleich" vorkommenden IDs arbeitet man nicht...

entweder benennst du die Spalte um oder hast wirklich eine ECHTE ID <- 
und die kommt nur 1x vor...

jetzt zum verständnis... du willst also JEDE ~falsche~ ID zurück 
bekommen? aber nur wo AC im Feld steht... <- stellt sich die Frage 
"welchen Sinn" ergibt die ID, denn man könnte auch einfach >AC< ausgeben 
und die ID Ignorieren...

=> Leider arbeite ich Hauptsächlich mit Oracle SQL, daher kann es sein, 
dass du manche Befehle nachgooglen musst wie diese in MY-SQL gehen...

mit DISTINCT kannst du z.B. die Tabelle einkürzen...

schreibst du:
> SELECT DISTINCT ID FROM TABLE
erhälst du deine ID 1 und deine ID 2 zurück <- alle anderen würden nur 
aufgedoppelt werden...

du kannst ebenso "unterselects" machen...

also z.B.
> SELECT * FROM ( SELECT ID FROM TABLE )

Das bringt dann was, wenn du "vorselektirern" möchtest um dann ggf. 2 
Tabellen zu verheiraten <- 1x deine Selektionstabelle und 1x deine echte 
Tabelle

> SELECT tabA.* FROM
> ( SELECT ID, WERT1 FROM TABLE WHERE WERT1 = 'AC' ) AS tabSEL
> LEFT JOIN TABLE AS tabA ON tabSEL.ID = tabA.ID

<- das Hilft dir zwar nicht exakt bei deiner Frage weiter, aber 
hoffentlich im "verständnis" wie SQL funktioniert!

für alles weitere hast du ja bereits antworten erhalten...

oder du musst deine Frage nochmal etwas tiefer konkretisieren :)

von Sheeva P. (sheevaplug)


Lesenswert?

Sebastian schrieb:
>
1
> Tabelle1
2
>  _______________________
3
> ID| Wert1 | Wert2 | Wert3|
4
> 1 |  AB   |   1   | blubb|
5
> 1 |  AC   |   2   | bla  |
6
> 1 |  AD   |   3   | egal |
7
> 1 |  AE   |   4   | bal  |
8
> 2 |  AB   |   5   | egal |
9
> 2 |  AC   |   6   | blub |
10
> 2 |  AD   |   7   | egal |
11
> 2 |  AE   |   8   | egal |
12
>
>
> Vereinfacht ausgedrückt, möchte ich, wenn in Wert1 "AC" steht, dass ich
> das Ergebnis aus Wert2 bekomme. Also in diesem Fall sollte ich für ID 1
> eine 2 zurückbekommen und für ID 2 eine 6.
>
>
1
> select
2
> ID,
3
> CASE WHEN Wert1 = 'AC' THEN 'Wert2'  ELSE 'nicht gefunden' END as Wert1,
4
> Wert3
5
> 
6
> from Tabelle1
7
> WHERE ID IN (1, 2)
8
> GROUP BY Wert3;
9
>
>
> Wie müsste das korrekt aussehen?
1
SELECT id, Wert2
2
FROM Tabelle 1
3
WHERE Wert1 = 'AC'
4
  AND id=?

Der Wert für "id" wird dabei als Parameter übergeben oder manuell 
eingesetzt.

von Sheeva P. (sheevaplug)


Lesenswert?

hans schrieb:
> also mit mehrfach "gleich" vorkommenden IDs arbeitet man nicht...

Aber ja doch, warum denn nicht?

> entweder benennst du die Spalte um oder hast wirklich eine ECHTE ID <-
> und die kommt nur 1x vor...

Was Du meinst, ist ein "primary key" oder, zu deutsch, 
"Primärschlüssel". Das ist ein Schlüssel, der den Datensatz eindeutig 
identifiziert, und der kann natürlich auch aus mehreren Spalten bestehen 
und nennt sich dann "composite primary key". Das Konzept existiert 
natürlich auch in Oracle.

Richtig ist allerdings auch, daß es etwas ungeschickt ist, eine Spalte 
"id" zu nennen, die für sich alleine gestellt kein Primärschlüssel ist, 
da viele Datenbanker diesen Namen nur für alleinstehende Primärschlüssel 
zu nutzen, während andere eher zu "<tabellenname>_id" tendieren. Aber 
auch, wenn das ungeschickt sein mag, bleibt es völlig legales SQL.

von hans (Gast)


Lesenswert?

@Sheeva Plug: aber das meine ich doch... es geht einfach nur um "eine 
saubere schreibweise" ...

wenn man xy_ID schreibt, ist alles gut, weil das dann auf eine 
"eindeutige" ID verweise...
das FELD ID Suggeriert aber einem 2. IMMER die Eindeutigkeit <- das ist 
weniger was funktionales (auch nicht der Primary Key) als "sauberer 
Stil"
<- gehen tut das klar...

ps.: mit Case geht das auch, aber schöner und performanter ist ein "left 
join"

von Peter II (Gast)


Lesenswert?

hans schrieb:
> ps.: mit Case geht das auch, aber schöner und performanter ist ein "left
> join"

warum sollte ein join performanter sein? Das muss viel mehr verglichen 
werden. der Case wirkt dagegen nur bei die "Ausgaben" und muss bei 
Ausführungsplan nicht berücksichtig werden.

von xxx (Gast)


Lesenswert?

Michael B. schrieb:
> Kannst du nicht mit dem zufrieden sein, was deine Datenbank liefert ?
> ...
> So durcheinander, daß man sich fragt, was du eigentlich willst.

=> Ich glaube das weiß der Fragesteller auch nicht so richtig, deshalb 
fragt er ja

Ich bin jetzt auch kein Experte in SQL aber so einen Code wie ganz oben 
sieht man wahrscheinlich so gut wie nie -> Anfänger

Deshalb zur Erklärung:
Eine Datenbank verwendet man meistens (sinnvollerweise) bei sehr vielen 
Einträgen. Einfach mal vorstellen, die Tabelle enthält 20000 Zeilen. Und 
die gewünschte Abfrage wäre nur in einer einzigen Zeile. Mit der 
Originalabfrage oben (sollte sie überhaupt funktionieren) würde man 
unter Umständen trotzdem 19999 Ausgaben erhalten mit 'nicht gefunden' 
und eine Ausgabe mit dem gewünschten Ergebnis. Viel Spaß beim suchen.

Die Abfragen werden verwendet um 'nur' das gewünschte Ergebnis zu 
präsentieren (der Rest ist ja dann irrelevant).

Passende Anweisungen wurden hier schon mehrfach gepostet, ich hätte 
ebenfalls es so gemacht:
1
SELECT id, wert2 FROM tabelle1 WHERE Wert2='AC'

von Jens G. (jensig)


Lesenswert?

Sheeva Plug (sheevaplug) schrieb:

>> select
>> ID,
>> CASE WHEN Wert1 = 'AC' THEN 'Wert2'  ELSE 'nicht gefunden' END as Wert1,
>> Wert3
>>
>> from Tabelle1
>> WHERE ID IN (1, 2)
>> GROUP BY Wert3;
>>

>>
>> Wie müsste das korrekt aussehen?

>SELECT id, Wert2
>FROM Tabelle 1
>WHERE Wert1 = 'AC'
>  AND id=?

 xxx (Gast) schrieb:
>Passende Anweisungen wurden hier schon mehrfach gepostet, ich hätte
>ebenfalls es so gemacht:

>SELECT id, wert2 FROM tabelle1 WHERE Wert2='AC'


Das ist aber nicht äquivalent mit dem, was der TO wollte.
Er will ja nicht nur die AC-Rows haben, sondern alle, die in seiner 
Beispieltabelle sind. Nur will er eben bei den AC-Rows den Wert2 anstatt 
den Wert1 sehen. So gesehen geht der Ansatz des TOs schon in die 
richtige Richtung, und wurde durch Peter II richtig korrigiert.
Das angesprochene Datentyp-Problem im CASE-Block kann man ja mit einem 
Cast auf Wert2 beheben, falls es wirklich eine Integerspalte sein 
sollte.

... char(Wert2) ...

(bin mir aber nicht sicher, ob diese Schreibweise bei mysql so gültig 
ist.
Ansonsten ... cast(wert2 as char) ... oder so ähnlich ...)

von Jens G. (jensig)


Lesenswert?

hans (Gast) schrieb:

>also mit mehrfach "gleich" vorkommenden IDs arbeitet man nicht...

Es könnte ja auch eine abhängige Tabelle sein, die via ForeignKey auf 
den PrimaryKey einer anderen Tabelle zeigt - dann könnte man mehrere 
gleiche IDs drin haben.
Aber das ist vermutlich noch nicht die Konstellation beim TO.

von hans (Gast)


Lesenswert?

@Jens G.

das ist zwar so Korrekt, aber genau das habe ich auch erläutert...

=> Das was du schreibst ist dann keine ID mehr sondern ein ID-Bezug! <- 
und das ist sozusagen die von mir beschriebene XY ID

Beispiel (auch für den Fragessssteller):
wir haben eine Adressliste und jede Person kann mehrere Telefonnummern 
haben

hier die Personen mit eindeutiger ID
1
ID Name
2
1  Jens
3
2  Hans

und hier die Telefonnummern mit ebenso eindeutiger id
1
ID pID Nummer
2
1  1   0123456789
3
2  2   0123456788
4
3  2   0123456787
5
4  2   0123456786

so hat Hans jetzt 3 Nummern und Jens 1 Nummer... das Feld ID (rein 
Sprachlich) ist IMMER eindeutig... das feld pID (wie PersonenID) 
verweist lediglich auf die ID in Tabelle 1

Select * FROM personen p, nummern n
WHERE p.pID = n.ID

nun erhalte ich JEDE zulässige Konstellation (in diesem Fall also 4 
Zeilen)

alternativ auch mit JOIN

Select * FROM nummern n
LEFT JOIN personen p --left listet auch wenn nicht gefunden
ON p.ID = n.pID

<- selbes ergebnis

von hans (Gast)


Lesenswert?

nachtrag... theoretisch braucht man die ID bei den Nummern nicht...
=> aber ich denke einen Schritt weiter: irgendwann will ich eine Nummer 
ändern oder Löschen und dann wirds plötzlich unnötig Kompliziert wenn 
ich keine ID habe

von Andreas E. (hismastersvoice)


Lesenswert?

Probier das mal aus (ungetestet, können noch kleine Fehler drin sein).
Ausgehend davon, das die Kombination aus id und wert1 eindeutig ist 
(besser wäre ein Primary Key), sollte das funktionieren.
Durch den Filter auf Wert1='AC' werden alle Werte im Select NULL, die 
nicht verknüpft werden können. Die Tab1 Werte bleiben wegen des LEFT 
JOINs aber erhalten.
Ist tab2.wert1 NULL, entspricht das Deinem 'nicht gefunden'.
Natürlich kann man das dahingehend auch noch anpassen.
1
SELECT tab1.id, tab2.wert1
2
FROM Tabelle1 AS tab1
3
LEFT JOIN Tabelle1 AS tab2 ON tab1.id=tab2.id and 
4
                              tab1.wert1=tab2.wert1 and 
5
                              tab2.wert1='AC'
6
WHERE tab1.ID IN (1, 2)

von hans (Gast)


Lesenswert?

@Andreas E.

einfach NVL(tab2.wert1, 'nicht gefunden')

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.