PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL-Query-Frage


07.07.2007
2009-09-16, 23:49:09
Hallo,

habe folgende Tabelle


beschreibung name
event a ralph
event a eddie
event b ralph
event b dieter
event c ralph
event c eddie
event c dieter


Ich brauche nun einen select der mir als ergebnis

event a
event c

bei eingabe von ralph und eddie


oder


event c

bei eingabe von dieter und eddie


oder


event c

bei eingabe von dieter, ralph und eddie


Sprich ein Query dem ich n namen im where gebe und es mir die beschreibungen zurueckgibt die jeweils alle der n namen hat.

Bitte um Hilfe

tsaG
2009-09-17, 00:27:11
Das Problem ist ja das SQL nicht genau weisst welchen Eddie und Ralph Du nun meinst, da er ja bei A und C steht, daher würde er dir eher
event a
event a
event b
event c
event c

ausgeben

SELECT beschreibung FROM tabelle WHERE tabelle.name = 'eddi' OR tabelle.name = 'ralph'



Meinst Du sowas? Ansonsten verstehe ich das nochnicht ganz.

EDIT: Hast Du die Tabelle schon?

Ansonsten würde ich die halt so machen:

beschreibung name name2 name3
event a ralph eddie
event b ralph dieter
event c ralph eddie dieter


Dann kannst es immer folgend machen:

SELECT beschreibung FROM `tabelle` WHERE `tabelle.name` = 'eddi' AND `tabelle.name2` = 'ralph'

tsaG
2009-09-17, 00:36:19
*delete*

RattuS
2009-09-17, 00:40:25
Ich bezweifle, dass man diese Logik in einem Statement zusammenpacken kann.

Gast
2009-09-17, 00:53:57
Man kann schon, falls die Anzahl der Parameter konstant ist. Dann muss man die Tabelle mit sich selbst joinen. Ist aber sehr unperformant, es ist normalerweise um einiges besser, alle Events zu holen und dann die Listen im Speicher zu bearbeiten (falls es hier um Programmierung und nicht reines Reporting geht).

SELECT a.event
FROM tabelle a, tabelle b
WHERE a.name=$Parameter1
AND b.name=$Parameter2
AND a.event = b.event

Wie gesagt, nicht empfohlen - aber so sollte es gehen.

Tiamat
2009-09-17, 09:00:44
Ja deine Idee ist schon richtig, du weißt, dass du nach Events suchst, an denen bestimmte Mitarbeiter arbeiten. Du könntest genau so nach allen Mitarbeitern suchen, die an bestimmten Events arbeiten. Wie man das halt möchte.

Mit der Where in Klausel kann man sich´s ziemlich einfach machen.



select beschreibung from TableX
where beschreibung in('event a', 'event c') AND
where name in('eddie', 'ralph')



Das wars..
Das hat auch den Vorteil, dass man da ruhig mal 4,5,6 Suchargumente in der Klausel übergeben kann, ohne die Whereklauseln auf 4,5,6 Zeilen auszuweiten.

Ich würde daraus aber ne gescheite Tabellenlandschaft machen.
Eine Tabelle Mitarbeiter, eine Tabelle Events, und eine Tabelle arbeitetAm(Fremdschlüssel auf Mitarbeiter, Fremdschlüssel auf Events)
, die quasi genau so organisiert ist, wie deine Tabelle.

Primärschlüssel würden auch net schaden, allein schon zu besseren Performance ^^

Gruß
Tiamat

wry
2009-09-17, 10:41:19
Sowas sollte auch gehn. Habe es allerdings nicht getestet:

SELECT beschreibung FROM Table_X WHERE name = 'eddie'
INTERSECT
SELECT beschreibung FROM Table_X WHERE name = 'ralph'

Weiß nicht ob folgendes Statement valide ist (eventuell benötigt man Klammerung?):

SELECT beschreibung FROM Table_X WHERE name = 'eddie'
INTERSECT
SELECT beschreibung FROM Table_X WHERE name = 'ralph'
INTERSECT
SELECT beschreibung FROM Table_X WHERE name = 'dieter'


Edit:
Aww.. hätte ich zuende lesen sollen, du möchtest das im WHERE haben -_-

Gast
2009-09-17, 13:58:00
meine fünf Cents

SELECT beschreibung,group_concat(name) as names
FROM TABLEX
GROUP BY beschreibung
HAVING names like "%dieter%" AND names like "%eddie%" AND ...

ist zwar für SQLite, sollte aber auch mit entsprechendem CONCAT in üblichem SQL gehen

Matrix316
2009-09-17, 23:25:39
müsste nicht einfach sowas gehen:


select distinct Beschreibung from Tabelle where Name = 'dieter' and Name = 'eddie'...


?

Durch distinct bekommt man nur [mindestens] ein Ergebnis und durch die ands wird die Auswahl eingeschränkt, da z.B. auswahl wo dieter UND eddie sind, nur z.B. c ist.

[Wobei natürlich group by das gleiche ergebnis liefert ;)]

Berni
2009-09-18, 00:44:08
Ich denke das müsste exakt 0 Ergebnisse liefern, da ein name nicht zugleich dieter und eddie sein kann. Das vom Gast darüber könnte aber tatsächlich funktionieren wenngleich es falsche Ergebnisse liefern kann bei Namensüberschneidungen, also wenn z.b. eine "maria" und eine "marianne" heißt.

Generell wäre eine richtige Normalisierung empfehlenswert, dann geht das auch vernünftig abzufragen.

Normal würde ich das mit einer CommonTableExpression machen aber das sieht mir hier eher nach nem MySQL-Problem aus und das kann das ja nicht. Vorausgesetzt, dass ein User zu einem event nur 0-1x zugeordnet werden kann würde ichs so machen:
SELECT beschreibung FROM TABLEX
Where name in ('dieter', 'eddie')
GROUP BY beschreibung
HAVING count(*) = 2
Sollte die genannte Bedingung mit den Anzahl events nicht erfüllt sein müsste man es umständlicher machen:
SELECT beschreibung FROM (
SELECT distinct beschreibung, name From TABLEX
Where name in ('dieter', 'eddie')
)
GROUP BY beschreibung
HAVING count(*) = 2
Die 2 muss natürlich vom Abfrageprogramm eingefügt werden. Sollte aber normal kein Problem sein. Sollte auch das nicht möglich sein muss man zumindest die Variablen 2x übergeben:
SELECT beschreibung FROM (
SELECT distinct beschreibung, name From TABLEX
Where name in ('dieter', 'eddie')
)
GROUP BY beschreibung
HAVING count(*) = (
Select count(*) FROM (
SELECT distinct name From TABLEX
Where name in ('dieter', 'eddie')
)
)
Ist dann aber nicht mehr korrekt wenn ein name gar nicht in der Tabelle vorkommt. Denn dann würde hier ein Ergebnis geliefert obwohl gemäß Logik meiner Meinung nach ja gar nichts geliefert werden sollte. Wenn möglich also die Zahl fest einsetzen.

Gast
2009-09-18, 12:38:09
select beschreibung from TableX
where beschreibung in('event a', 'event c') AND
where name in('eddie', 'ralph')


Das geht leider nicht, da du ja das gewünschte Ergebnis in die WHERE-Klausel packst - du weisst ja nicht vorher, dass du nach event a und c filterst, sonst könntest du dir das SQL ja sparen. ;)

Wobei die GROUP-Sachen von Berni auch recht elegant sind.

Gast
2009-09-18, 14:06:14
SQL is fun - auch wenn man die Daten nicht so hat, wie man sie eigentlich bräuchte, kann man eine Menge machen

am besten gefallen mir bisher #5 (JOIN) und #8 (GROUP_CONCAT und HAVING) - letztlich geht es imho darum, die Daten intern (während der Abfrage) in die Form event-name-name-.. zu bringen - das geht auch mit Sub-Queries:

SELECT beschreibung FROM TABLEX
WHERE beschreibung IN (SELECT beschreibung FROM TABLEX WHERE name='ralph') AND
beschreibung IN (SELECT beschreibung FROM TABLEX WHERE name='eddie') [AND]
...
GROUP BY beschreibung

das wird bei mehr Namen aber eher unübersichtlich - daher mein Favorit (für MySQL "verbessert"): #8

SELECT beschreibung FROM TABLEX
GROUP BY beschreibung
HAVING GROUP_CONCAT(name ORDER BY name)=$PARAM$

$PARAM$ - 'eddie,ralph'
- 'dieter,eddie'
- 'dieter,eddie,ralph'
Namensabfragen müssen immer sortiert sein

Matrix316
2009-09-20, 00:59:33
Ich denke das müsste exakt 0 Ergebnisse liefern, da ein name nicht zugleich dieter und eddie sein kann.[...]

Stimmt stimmt stimmt... Mit Or gehts dann auch net, weil man beide Beschreibungen kriegt...

Tiamat
2009-09-20, 08:10:09
Das geht leider nicht, da du ja das gewünschte Ergebnis in die WHERE-Klausel packst - du weisst ja nicht vorher, dass du nach event a und c filterst, sonst könntest du dir das SQL ja sparen. ;)

Wobei die GROUP-Sachen von Berni auch recht elegant sind.

Hi,
das geht schon. Wenn man die 3. Zeile weglässt, so wären es sogar nur 2 Zeilen,
bekommt man alle Events, an denen Eddie und Ralph arbeiten. Man kann sich dann durch die eventuell lange Liste wühlen, oder tut es aus Arbeitgebersicht, wenn man bereits eine gewisse Vorstellung hat, wie ne Art Frage. Wie war das nochmal, arbeitet jetzt Eddie am Event a oder war´s nochmal Event c, und wo arbeitet Ralph nochmal und wo arbeiten beide ?

Klar ich weiß, solche Informationen sind nur in der Datenbank gespeichert und der Arbeitgeber setzt sich natürlich vor sein Mysql tätigt die Anfragen manuell ;D