2016-05-20 11 views
0

Ich habe eine linke Join-Abfrage, um Beiträge von einem Benutzer gefallen zu bekommen. wenn 2. angemeldeter Benutzer besucht das erste Benutzerprofil wird die Gleichen von ersten Nutzer zeigt und zeigt auch einen Text auf der Post, wenn der 2. Benutzer (angemeldeten Benutzer) wie die gleiche Postist es sicher, eine andere Abfrage in der Seite eine MySQL-Schleife zu laufen

Benutzertabelle

user_id | username 

mag Tisch

like_id | post_id | uid 

MySQL

$SQL = "SELECT * FROM likes LEFT JOIN users ON users.user_id = likes.uid WHERE likes.uid = 'user1'" 

Wenn ich eine weitere Abfrage innerhalb des wh laufen ile Schleife von oben Abfrage wird es funktionieren

$check_id = row['post_id']; //get post id from 1st loop 

if(isset($_SESSION['userid'])){ 

    $check = "SELECT * FROM likes WHERE post_id='$check_id' AND uid='LOGED-IN-USER-ID'" 

} 

Dann kann ich die num_rows bekommen und Text hinzufügen. Das funktioniert ganz gut, aber ich möchte wissen, gibt es eine bessere Möglichkeit, dies zu tun, ohne so viele Abfragen innerhalb der While-Schleife. Gibt es eine Möglichkeit, die Abfragen zu kombinieren oder die zweite Abfrage außerhalb der Schleife durchzuführen.

+0

Ich sehe nicht, Ihre 'while' Schleife – Justinas

+0

ist sicher wieder in der Schleife abfragen, natürlich, aber die erste SQL hat bereits alles enthalten (SELECT * FROM likes), daher ist Ihre 2. Anfrage wahrscheinlich nutzlos. – Raptor

+0

nein es ist nicht nutzlos, weil die zweite Abfrage überprüft, ob der angemeldete Benutzer auch den gleichen Beitrag mag. Problem ist, dass die Abfrage wird so oft wiederholt, wenn innerhalb einer While-Schleife – max

Antwort

2

Zufrieden haben, dass „sicher“ aus „Datenkonsistenz Sicht“ ist, aber in einem beim Abfragen Nachdem eine Abfrage als "1 + N" bezeichnet wird und in der Regel ein Performance-Killer ist, finden Sie leicht eine Dokumentation zum SQL 1 + N-Problem.

Die Lösung ist, den SQL-Server den Auftrag für Sie in einer einzigen Abfrage ausführen zu lassen und dabei Ping Pong zu vermeiden (lesen Sie: TCP-Pakete hin und her, Abfrage analysieren, ...).

Gegeben:

> SELECT * FROM user; 
+---------+----------+ 
| user_id | username | 
+---------+----------+ 
|  1 | root  | 
|  2 | user2 | 
|  3 | user3 | 
+---------+----------+ 


> SELECT * FROM `like`; 
+---------+---------+---------+ 
| like_id | post_id | user_id | 
+---------+---------+---------+ 
|  1 |  1 |  1 | 
|  2 |  2 |  1 | 
|  3 |  3 |  1 | 
|  4 |  4 |  1 | 
|  5 |  2 |  2 | 
+---------+---------+---------+ 

> SELECT * FROM `post`; 
+---------+--------+ 
| post_id | text | 
+---------+--------+ 
|  1 | post 1 | 
|  2 | post 2 | 
|  3 | post 3 | 
|  4 | post 4 | 
+---------+--------+ 

Es gibt mehrere Wege, was Sie anfordern möchten, aber ein Weg sein kann:

> SELECT like_id, like.post_id, text, 
     (SELECT 1 FROM `like` 
      WHERE post_id = post.post_id AND 
       user_id = 2 /* logged in user */) AS I_like_it_too 
    FROM `like` 
    JOIN post USING (post_id) 
    WHERE user_id = 1 /* user id of seen profile */; 

+---------+---------+--------+---------------+ 
| like_id | post_id | text | I_like_it_too | 
+---------+---------+--------+---------------+ 
|  1 |  1 | post 1 |   NULL | 
|  2 |  2 | post 2 |    1 | 
|  3 |  3 | post 3 |   NULL | 
|  4 |  4 | post 4 |   NULL | 
+---------+---------+--------+---------------+ 

Die Verwendung der I_like_it_too alias Beitrag anzuzeigen unterschiedlich je nach Bedarf.

Aus Leistungsgründen benötigen Sie einen Index auf like.user_id, um die ausgewählten Zeilen auf eine kleine Teilmenge zu beschränken, die abhängige Unterabfrage wird nur für diese Teilmenge ausgeführt, also ist das OK.

Eine weitere Möglichkeit sein kann:

> SELECT displayed.like_id, displayed.post_id, text, my_likes.like_id is not null AS i_also_like 
    FROM `like` AS displayed 
    JOIN post USING (post_id) 
LEFT JOIN `like` AS my_likes ON 
      displayed.post_id = my_likes.post_id AND 
      my_likes.user_id = 2 /* logged user */ 
    WHERE displayed.user_id = 1 /* user id of seen profile */; 

+---------+---------+--------+-------------+ 
| like_id | post_id | text | i_also_like | 
+---------+---------+--------+-------------+ 
|  1 |  1 | post 1 |   0 | 
|  2 |  2 | post 2 |   1 | 
|  3 |  3 | post 3 |   0 | 
|  4 |  4 | post 4 |   0 | 
+---------+---------+--------+-------------+ 
+0

Dank kann ich wissen, was ist 1 in 'SELECT 1 FROM like'? – max

+0

@max ein Wert. Dummy, wahr, Wert. "SELECT 1" ist in SQL gültig, also "SELECT 1 FROM table WHERE ..." ergibt 1 wenn WHERE übereinstimmt und NULL (was weniger wahr ist als 1) wenn where nicht übereinstimmt. –

+0

danke. Ich habs. – max

0

Meinst du das so?

Tabelle SO_LIKES (ur "Like" Table)

like_id | post_id | uid 
     1 |  1 | 1 
     2 |  2 | 1 
     3 |  1 | 2 

Tabelle SO_USERS (ur "Benutzer" Tabelle)

user_id | username 
     1 | User1 
     2 | User2 

SQL

SELECT * FROM SO_LIKES as t1 LEFT JOIN SO_USERS as t2 ON t1.uid = t2.user_id INNER JOIN SO_LIKES as t3 ON t1.post_id = t3.post_id WHERE t2.user_id = 1 AND t3.uid = 2 

SO Rufen Sie einfach die gleiche Tabelle in ur Abfrage erneut und verwenden Sie die ID von Benutzer 2 dort

WHERE t2.user_id = 1 AND t3.uid = 2 

Ausgabe sieht dann folgendermaßen aus

like_id | post_id | uid | user_id | username | like_id | post_id | uid 
     1 |  1 | 1 |  1 | User1 |  3 |  1 | 2 

SO erhalten u die post_id 1 Dass beiden Benutzer

Verwandte Themen