if then else & count

ramboni

Benutzer
Beiträge
17
Hallo zusammen,

SQL ist für mich noch sehr neu aber ich hoffe ihr könnt mir helfen.

Meine Datenbank sieht so aus: (m =männlich, w = weiblich)

Vorname, Geschlecht
Tom,m
Ilse,w
Eike,m
Eike,w

Ich habe ca 2000 Unisex Namen in der Datenbank, ich wollte anfangen alle per Hand auf 'u' zu ändern,
ich habe aufgegeben und suche nun eine Lösung per SQL.

Was soll passieren?

Wenn ich nur genau einen Treffer habe soll das Geschlecht ausgegeben werden.
Wenn es mehr als ein Treffer gibt, soll ein 'u' für unisex ausgegeben werden.

Was hab ich versucht? So ziemlich alles :(


Das hier klingt in meiner Welt logisch, ist es für SQL anscheinend nicht.

select case when count(Vorname) > 1 then 'u'
else Geschlecht
end

from Vornamen
where Vorname = 'Eike'


Könnt ihr mir helfen?
 
Werbung:
Du willst ja sicherlich Deine Vornamen-Tabelle als Nachschlagetabelle verwenden, also braucht diese einen Primary Key auf den vornamen. Du hast nun die Chance, das alles richtig zu machen.

Code:
test=*# select * from ramboni ;
 name | geschlecht
------+------------
 Tom  | m
 Ilse | w
 Eike | m
 Eike | w
(4 Zeilen)
test=*# create table vornamen(name text primary key, geschlecht char);
CREATE TABLE

test=*# with anzahl as (select name, count(1) from ramboni group by name) select name, geschlecht from ramboni where name in (select name from anzahl where count=1) union select name, 'u' from anzahl where count = 2;
 name | geschlecht
------+------------
 Tom  | m
 Eike | u
 Ilse | w
(3 Zeilen)

test=*# insert into vornamen select * from (with anzahl as (select name, count(1) from ramboni group by name) select name, geschlecht from ramboni where name in (select name from anzahl where count=1) union select name, 'u' from anzahl where count = 2) temp;
INSERT 0 3
test=*# select * from vornamen ;
 name | geschlecht
------+------------
 Tom  | m
 Eike | u
 Ilse | w
(3 Zeilen)

test=*# select * from vornamen ;
 name | geschlecht
------+------------
 Tom  | m
 Eike | u
 Ilse | w
(3 Zeilen)

test=*# \d vornamen
  Tabelle »public.vornamen«
  Spalte  |  Typ  | Attribute
------------+--------------+-----------
 name  | text  | not null
 geschlecht | character(1) |
Indexe:
  "vornamen_pkey" PRIMARY KEY, btree (name)

test=*#

Rollback & Kaffee.
 
Eigentlich ginge es auch ohne PK.
Code:
SELECT   t.vorname,
     ( CASE WHEN count(*) = 1 THEN max(t.geschlecht) ELSE 'u' END ) AS geschlecht
FROM   (

SELECT   DISTINCT vorname,geschlecht
FROM   tabelle

     ) t
GROUP BY t.vorname
 
Hallo zusammen,

also das Statement von "ukulele" funktioniert perfekt (siehe Anhang).
Ich verstehe es "noch" nicht komplett aber es funktioniert. Vielen Dank dafür!

Bei den Statements von "akretschmer" sehe ich noch viele Bäume aber nicht ansatzweise
einen Wald :) Da werd ich noch viel üben müssen.
Welche Probleme meinst du im Zusammenhang mit Foreign Key?
 

Anhänge

  • SQL.jpg
    SQL.jpg
    48,5 KB · Aufrufe: 6
Ich nochmal, hab das jetzt so gemacht:

select ( Case when Count(*) > 1 then 'u' ELSE max(geschlecht) end) as Geschlecht
from Vornamen
where Vorname = 'Eike'


Tatsächlich war "max" das Element das mir in meinen 99 Stunden Tests gefehlt hatte.
Obwohl in diesem Fall nur ein Wert zurück kommt, muss max verwendet werden, hmmm
Ist bestimmt total unsauber und doof aber so versteh ich es :)
 
Zuletzt bearbeitet:
Bei den Statements von "akretschmer" sehe ich noch viele Bäume aber nicht ansatzweise
einen Wald :) Da werd ich noch viel üben müssen.
Welche Probleme meinst du im Zusammenhang mit Foreign Key?

Was soll denn irgend wann mal das Ziel sein?

Du willst ja sicher abfragen können, was für ein Geschlecht ein gegebener Vorname hat.

Code:
test=# create table vornamen (vorname text primary key, geschlecht char, check (geschlecht in ('w','m','u')));
CREATE TABLE
test=*# insert into vornamen values ('Tom','m');
INSERT 0 1
test=*# insert into vornamen values ('Ilse','w');
INSERT 0 1
test=*# insert into vornamen values ('Eike','u');
INSERT 0 1
test=*# create table personen (vorname text references vornamen, nachname text);
CREATE TABLE
test=*# insert into personen values ('Tom','Musterman');
INSERT 0 1
test=*# select p.vorname, p.nachname, v.geschlecht from personen p left join vornamen v using (vorname);
 vorname | nachname  | geschlecht
---------+-----------+------------
 Tom  | Musterman | m
(1 Zeile)

test=*#

Was aber passiert, wenn Du in Personen einen Vornamen eingibst, den es in der Vornamen-Tabelle nicht gibt? Richtig, es kann nicht abgefragt werden. Daher der Foreign Key in meinem Beispiel.

Code:
test=*# insert into personen values ('Max','Müller');
FEHLER:  Einfügen oder Aktualisieren in Tabelle »personen« verletzt Fremdschlüssel-Constraint »personen_vorname_fkey«
DETAIL:  Schlüssel (vorname)=(Max) ist nicht in Tabelle »vornamen« vorhanden.
test=*#
 
Hallo,

ich bin mir sicher dass du Recht hast und ich mich Schlüsseln noch sehr intensiv auseinandersetzen muss.

Meine derzeitige Lösung ist folgende:

select ( Case when Count(*) > 1 then 'u'
when Count(*) = 1 then max(geschlecht)
when Count(*) = 0 then ''
end) as Geschlecht

from Vornamen
where Vorname = 'Max-Luca'

Ich bekomme so immer genau einen Wert zurück den ich in der Anwendung weiterverarbeiten kann.
 
Ich bekomme so immer genau einen Wert zurück den ich in der Anwendung weiterverarbeiten kann.

Mag sein, das taugt als nicht als Foreign Key. Das verhindert auch nicht, daß Du 37 mal 'w', 96 mal 'm' und 234 mal 'u' für 'max-Luca' einträgst, und das verhindert auch nicht, daß irgendwo ein 'Klaus-Bärbel' ist, wo Du mit Deiner Abfrage kein Resultat bekommst.
 
Du kannst auch min() nehmen, ist völlig humpe. Es muss nur Text aggregieren können und da nur ein Text da ist ist das dann auch zwangsläufig der richtige. Wenn du gruppierst müssen alle Spalten entweder gruppiert oder aggregiert werden, das ist vermutlich der am wenigsten beachtete Grundsatz in einer Welt voller MySQL.

Was das mit dem FK angeht bin ich mir nicht ganz sicher wie du vorgehst. Es wäre schon sinnvoll eine Tabelle mit Vornamen mit einem PK zu nutzen und keine doppelten Einträge zu führen. Andererseits musst du natürlich den Inhalt erstmal ermitteln, also initial deinen Datenbestand von 2 Datensätzen mit m und w auf einen mit u anpassen. Dann muss diese "Arbeit" nicht jedesmal durchgeführt werden. Dann kann theoretisch auch der Vorname der PK sein...
 
Ju,

das min, max Ding hab ich verstanden. Coole Sache.
Ich denke ich habe mich in meinem ersten Post auch falsch ausgedrückt.

Ich möchte die beiden Datensätze nicht zusammenführen da ich ja sonst die Einzelinfos verlieren würde (siehe Bild).
Das war aber zu dem Zeitpunkt das einzige dass mir eingefallen ist als Lösung.

Allerdings brauche ich für die Anwendung ein Kennzeichen ob der User die Anrede richtig oder falsch gewählt hat.
Bei 'u' lass ich dann einfach "Herr" und "Frau" zu. Bei 'm' nur "Herr'.
Sprich: Ich sage der Anwendung: Guck was der User gewählt hat > Herr > also mache aus Herr ein "m".
Dann setze ich das Statement ab und gucke was z.B. bei "Thomas" zurück kommt. Ein "m" ,ok die Anrede ist also richtig.
Kommt jetzt ein "u" zurück kann die Anrede auch richtig sein. Kommt ein "w" zurück" ist sie def. falsch und ich
kann drauf reagieren.
(Außer es ist ein Doppelname bei dem der Zweitname das Geschlecht angiebt.. aber das ist noch ein anderes Thema
und stimmt wohl auch nicht zu 100% )

FK/PK: Im Moment habe ich in der Datenbank genau die Felder die im Bild zu sehen sind. Mehr nicht.
Hab das aus ner Textdatei einfach mal eingelesen und geguckt was passiert :)

2do für mich: Was sind eigentlich diese FK's und PK's ?

Jeder hat mal angefangen :)
 

Anhänge

  • VName.jpg
    VName.jpg
    25,8 KB · Aufrufe: 2
Werbung:
FK = foreign key = Fremdschlüssel
PK = primary key = Primärschlüssel

Wenn du die Daten alle hast gleiche ich die gerne auch mal mit meinem CRM ab :) Ich mache außerdem eine Autovervollständigung, wenn also mehr als 95% aller "Andrea"s eine Frau sind wird sie auch "Frau" als Anrede vervollständigen. Dazu muss ich allerdings die Einträge in der Personentabelle zählen und habe bisher keine Liste aller Vornamen.
 
Zurück
Oben