2016-04-28 12 views
1

Ich habe diese Tabellen:mit mehreren Reihen

Blogs

id 
name 
user_id // author - relational to "users" 

Benutzer

id 
nickname 
avatar 

suscriptions

id 
blog_id // relational to "blogs" 
user_id // relational to "users" 

Die Idee ist, auf der Seite, so etwas zu zeigen:

Blogname 
Created By Stack 
Suscriptions: Overflow, Easy, Robinson, Porter 

ich alle Daten von blogs holen

SELECT 
    b.id, 
    b.name, 
    b.user_id, 
    u.nickname as user_nickname, 
    u.avatar as user_avatar 
FROM blogs b 
LEFT JOIN users u ON b.user_id = u.id 

Mit PHP habe ich ein Array mit allen blogs ID, so Ich kann sie mit IN-Operator, wie folgt verwenden:

SELECT 
    s.id, 
    s.blog_id, 
    u.nickname, 
    u.avatar 
FROM suscriptions s 
LEFT JOIN users u ON s.user_id = u.id 
WHERE s.blog_id IN (1, 2, 3) 

Und t Wieder PHP zum Sortieren des Ergebnisses.

Aber gibt es einen besseren Weg? Ich habe darüber nachgedacht, nur MySQL und nicht PHP zu verwenden. Vielleicht alle Daten in nur einer Abfrage abrufen? Oder was wäre der beste Weg, um das zu bekommen?

Es ist wichtig zu beachten, dass ein blog mehrere subscriptions haben kann.

Ich fand diese Frage von 2012, die ein wenig ähnlich ist: JOIN three tables and aggregate data from multiple rows for every DISTINCT row in separate column Aber das OP sagt, dass es wirklich langsam ist, also bin ich jetzt ein wenig verloren.

+0

Haben Sie Kern PHP oder einige Frameworks verwenden? –

+0

@SultanAllaudeen nur PDO für Datenbankbehandlung –

Antwort

0

Ich denke, was Sie brauchen, ist es, alle Zeilen, die von den "Join-Beschreibungen" generiert werden, zu gruppieren und sie mit einem Komma für die Präsentation zu verketten.

SELECT 
    b.id AS blog_id, 
    b.name AS blog_name, 
    u.nickname AS user_create_nickname, 
    u.avatar AS user_create_avatar, 
    GROUP_CONCAT(us.nickname SEPARATOR ', ') AS users_suscritions 
FROM blogs b 
INNER JOIN users u ON b.user_id = u.id 
LEFT JOIN suscriptions s ON s.blog_id = b.id 
LEFT JOIN users us ON s.user_id = us.id 
GROUP BY b.id; 
+0

Wirklich hilfreich, danke! Aber ich hätte auch gern die Info des Abonnements, weil es andere Spalten wie Datum usw. haben wird. Entschuldigung dafür, das nicht auf der Frage zu erklären. –

+0

Ich verstehe, in diesem Fall, so weit ich weiß, brauchen Sie wirklich zwei Abfragen – Doglas

+0

Die 'GROUP_CONCAT' funktioniert jetzt gut, danke! –

0

Sie können jede der beiden tun. Mehrere kleine Abfragen oder eine große Abfrage mit mehr Joins oder (sogar Unterabfragen), um alle Daten auf einmal zu erhalten. Sie werden keinen Unterschied in der Leistung feststellen, bis Sie zu großen Datenmengen kommen.

Wenn Sie gerade mit PHP beginnen, würde ich vorschlagen, kleinere Abfragen zu haben, die einfacher zu debuggen und zu verstehen sind. Schließlich ist MySQL gut für kleine schnelle Abfragen geeignet.

Bald genug, Sie bewegen sich zu einem ORM (oder einem Framework), die die Abfragen für Sie schreiben wird. Sie müssen sich nur auf die Logik des Problems konzentrieren, das Sie zu lösen versuchen.

$blogs = $this->Blog->find('all') 

Und da ein Blog zu einem User gehört und ein User können viele haben Subscriptions, werden alle Daten „automatisch“ abgerufen werden (It:

Zum Beispiel in CakePHP würden Sie nur tun müssen, würde das SQL für die Join-Tabellen selbst erzeugen wie das in Doglas's answer).

So jetzt, würde ich auf den Aufbau kleine Abfragen konzentrieren beraten, die leicht, debug, optimize und halten zu verstehen.

Hier ist a list of ORMs in PHP. Und das sind ziemlich häufig:

  1. aus dem Team Laravel.
  2. Propel

Und here is ein Beitrag über ORMs aus dem gleichen Blog;)

+0

Ich wusste das nicht, es scheint wirklich praktisch, danke, ich werde es mir gleich ansehen! –

Verwandte Themen