# [MySQL] JOIN nur, wenn ein bestimmtes Feld einen bestimmten Wert aufweist



## suntrop (12. November 2011)

Mein kleines Projektmanagement-Tool übersteigt gerade meine aktuellen Fähigkeiten  Folgendes  … ich will zu jedem Projekt speichern, ob entweder alle oder nur bestimmte Personen Zugriff haben. Leider kann ich das nicht so richtig in SQL dolmetschen.

In der Tabelle für Projekte habe ich ein ENUM mit 'all', 'privat', 'selected'. Erstgenanntes sollte klar sein. Zweite Erlaubnis soll nur dem User Zugriff geben, der das Projekt erstellt hat. Und Selected soll in einer anderen Tabelle gespeicherte Zugriffsrechte heranziehen.

Mein Problem ist jetzt, dass ich nicht weiß wie ich beim Auslesen Punkt 2 und 3 prüfe und entsprechende Resultate aus der DB hole.

Das hier ist mein aktueller Versuch

```
SELECT id, title

IF(
	p_projects.permission = selected,
		INNER JOIN project_permissions
			ON p_project_permissions.project_id = p_projects.id
		
		WHERE p_project_permissions.user_id = $USERID
)

IF(
	p_projects.permission = privat,
		WHERE p_projects.created_by_user_id = $USERID
)


FROM `p_projects`
```

Bitte nicht schimpfen, ist mein erster Versuch mit IF ELSE unter MySQL 

Wäre super, wenn mir jemand helfen könnte.

Grüße
suntrop


----------



## CPoly (12. November 2011)

Willst du jetzt Abfragen, ob ein bestimmter Nutzer auf ein bestimmten Projekt zugreifen kann? Oder was soll als Ergebnis kommen?


----------



## suntrop (12. November 2011)

Das Ergebnis soll sein, dass ich eine Liste aller Projekte erhalte, auf die ein bestimmter User (kommt per PHP, im Code $USERID) Zugriff hat.


----------



## Lime (12. November 2011)

INNER JOIN project_permissions
            ON p_project_permissions.project_id = p_projects.id


Also mir fällt da vor allem auf, dass du zwar die gleiche Tabelle meinst, die aber unterschiedlich heißen?
Desweiteren liest du gar nicht die Art der Rechte/die Rechte selber aus...
Habs auch nicht so mit Mysql, deswegen kann ich dir auch nicht direkt eine Lösung anbieten.
€: Theoretisch kann der Ersteller ja immer auf sein Projekt zugreifen, oder?
€2: Wo findet man die Rechte, die ein bestimmter User hat? Das wäre bei einer selected-permissions Abfrage hilfreich.
€3:
jetzt begreif ich auch so langsam, was du machen willst...
€3:
mal ein Versuch

```
SELECT id, title 
FROM `p_projects`
IF(
    p_projects.permission = selected,
        INNER JOIN p_project_permissions
            ON p_project_permissions.project_id = p_projects.id
        
        WHERE p_project_permissions.user_id = '".$USERID.'"
)
 
IF(
    p_projects.permission = privat,
        WHERE p_projects.created_by_user_id = '".$USERID."'
)
```

inner join nach dem FROM...

gruß


----------



## suntrop (12. November 2011)

Sorry, das sind die selben Tabellen, nur das Prefix fehlt.
Richtig, der Ersteller soll immer auf sein Projekt Zugreifen dürfen.

Hier mal meine anderen Versuche …


```
SELECT p_projects.id, title, permission, project_id, user_id
FROM  `p_projects`

LEFT JOIN p_project_permissions
  ON ( p_project_permissions.project_id = p_projects.id )



/*
IF( p_projects.permission = selected,user_id=2,1=1)

IF( p_projects.permission = selected, WHERE user_id = 2) 

WHERE
  CASE  WHEN p_projects.permission = 'selected'  THEN  user_id = 2 END

*/
```


----------



## CPoly (12. November 2011)

Ich denke für diesen Fall wäre ein UNION wesentlich besser als diese IF-Abfragen.


```
SELECT id, title FROM p_projects WHERE permissions = 'all'
UNION
SELECT id, title FROM p_projects WHERE permissions = 'privat' AND created_by_user_id = $USERID
UNION
SELECT id, title FROM p_projects
JOIN (project_permissions) ON (p_project_permissions.project_id = p_projects.id AND p_project_permissions.user_id = $USERID)
WHERE permissions = 'selected'
```


Edit: Und falls im Falle von "selected" der Ersteller nicht nochmal extra in der permissions Tabelle auftaucht, kannst du das auch noch mit rein nehmen.



```
SELECT id, title FROM p_projects WHERE permissions = 'all'
UNION
SELECT id, title FROM p_projects WHERE permissions IN ('privat', 'selected') AND created_by_user_id = $USERID
UNION
SELECT id, title FROM p_projects
JOIN (project_permissions) ON (p_project_permissions.project_id = p_projects.id AND p_project_permissions.user_id = $USERID)
WHERE permissions = 'selected'
```


----------



## Lime (12. November 2011)

Für was genau willst du die Projekte auslesen?
Liest der Benutzer SEINE Projekte aus?
Liest du die Projekte von bestimmten Benutzern aus (control panel)?
Liest ein anderer Benutzer die Projekte aus (auch von anderen Benutzern), wo er dran arbeiten kann?

kompliziert ich weis...^^

€:

```
SELECT id, title FROM p_projects WHERE permissions = 'all'
UNION
SELECT id, title FROM p_projects WHERE permissions = 'privat' AND created_by_user_id = $USERID
UNION
SELECT id, title FROM p_projects
JOIN (p_project_permissions) ON (p_project_permissions.project_id = p_projects.id AND p_project_permissions.user_id = $USERID)
WHERE permissions = 'selected'
```
nur den einen tabellennamen richtiggestellt....


----------



## suntrop (12. November 2011)

Mit dem €3 Code erhalte ich diese Fehlermeldung …

SELECT id, title
FROM p_projectsIF( p_projects.permission = selected, 
INNER JOIN p_project_permissions ON p_project_permissions.project_id = p_projects.id
WHERE p_project_permissions.user_id =1 ) 
LIMIT 0 , 30

MySQL meldet: 

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF(
    p_projects.permission = selected,
        INNER JOIN p_project_permissio' at line 3 

… außerdem logt verliert PHPMyAdmin die Verbindung zur Datenbank****** Das hatte ich bisher auch noch nicht


----------



## Lime (12. November 2011)

Ok, das ist nicht gut. also hab damit jetzt nicht viel Erfahrung, könnte mir nur einen Formatierungsfehler vorstellen.

SELECT id, title
FROM p_projects
IF( p_projects.permission = selected, 
INNER JOIN p_project_permissions ON p_project_permissions.project_id = p_projects.id
WHERE p_project_permissions.user_id =1 ) 
LIMIT 0 , 30

vor dem IF war kein Abstand drin..., aber obs daran liegt? Ich bastel zu wenig mit Mysql, dass ich solche fehler ausschließen könnte...


----------



## CPoly (12. November 2011)

An der Stelle wo ihr das "IF" habt, wird eben keines erwartet. Es wird z.B. ein WHERE erwartet. So kann man das IF nicht verwenden.


----------



## suntrop (12. November 2011)

Super! Das mit dem UNION funktioniert 

Besten Dank an euch beide für die Unterstützung!

Das mit dem IF muss ich mir nochmal ansehen, warum das an dieser Stelle nicht verwendet werden darf. Und UNION muss ich mir in jedem Fall auch ansehen


----------



## Lime (12. November 2011)

Ich kuck mir UNION auch mal an, kenn ich selber auch noch nicht.
Meine Abfragen waren entweder total simpel - oder eben auch total "deppad". Ne Abfrage, die man nur mit Nachdenken lösen könnte, hatte ich selber noch nie. Immer gleich die voll gestörten Probleme mit sehr extravaganten Lösungen...

PS: Darf man Erfahren, was das Projekt (über Projekte) für ein Projekt ist? (wer bietet mehr Projekt-Wörter in einem Satz? )


----------



## CPoly (12. November 2011)

UNION ist nichts weiter als die Vereinigung der Ergebnisse mehrerer getrennter Abfragen zu einer. Zu beachten ist, dass die Anzahl und der Typ der jeweiligen Felder der Abfragen identisch sind.


----------



## Lime (12. November 2011)

Also theoretisch könnte man drei Abfragen vereinen, wenn jetzt zwei Abfragen jeweils ein Ergebnis ausspucken (dass Ergebnis ist beide Male dasselbe), kommt das Ergebnis dann zwei Mal oder nur einmal raus?


----------



## CPoly (12. November 2011)

Wenn zwei Abfragen ein identisches Ergebnis liefern, bekommst du das zwei mal. Das ist ja bei einem normalen SELECT genauso. Du kannst wie bei SELECT ein DISTINCT benutzen, um es eindeutig zu machen.


----------

