2016-05-03 4 views
0

Ich habe versucht, eine Unterabfrage zu arbeiten, aber ich denke, es muss stattdessen beizutreten, aber ich bin neu in Datenbanken und hat eine harte Zeit, wickeln meinen Kopf herum, wie es funktioniert.MYSQL Sub Abfrage mit zwei Spalten

Ich muss eine Zeile von Benutzerprofil basierend auf drei Spalten in Verbindung sammeln, was ich habe, die nicht funktioniert, ist dies.

SELECT * FROM userprofile WHERE user_id IN 
(SELECT connect.user_id, connect.connect_to_id FROM connect WHERE 
(user_id = '1' OR connect_to_id = '1') AND is_connected = '1'); 

Da die zweite SELECT zwei Spalten aufgelistet es Fehler mit

#1241 - Operand should contain 1 column(s) 

nur eine Spalte Nachdem in der zweiten aufgeführt kommen nicht alle Einträge zurückzukehren, nur diejenigen, die der erste Test erfüllt.

Muss dies mit JOIN geschehen und wenn ja wie? Jede Verknüpfung, die ich versuche, führt dazu, dass alle Einträge aus der Benutzerprofiltabelle zurückgegeben werden.

Danke für Ihre Hilfe.

* UPDATE

Ich habe zwei Anfragen jetzt arbeiten.

SELECT u.* FROM userprofile u 
JOIN connect c ON (u.user_id = c.user_id OR u.user_id = c.connect_to_id) WHERE 
    ((c.user_id = '1' OR c.connect_to_id = '1') AND c.is_connected = '1') AND u.user_id != '1' 
GROUP BY u.id; 

Und

SELECT u.* FROM userprofile u WHERE u.user_id IN 
(SELECT connect.user_id FROM connect WHERE connect.connect_to_id = '1' AND connect.is_connected = '1' 
UNION ALL 
SELECT connect.connect_to_id FROM connect WHERE connect.user_id = '1' AND connect.is_connected = '1') 

Über 10000 Anrufe mit micro Ich habe die zweite die Sub-Abfrage mit schneller ein bisschen zu sein.

Join Query:4.6199560165405 
Sub Query:4.0528790950775 

Ich habe dann beschlossen, einen Test zu tun, warum zu sehen und entdeckt, dass die GROUP BY-Befehl deutlich das JOIN verlangsamt. Also mit der GROUP BY entfernt bekomme ich diese Zahlen.

Join Query:2.6410460472107 
Sub Query:4.1510140895844 

Es stellt sich heraus, dass ich nicht wirklich brauchen, die GROUP BY, wie ich bin, dass u.user_id Kontrolle! = ‚1‘ und dies stoppt das gleiche Problem, das ich war.

Also die Frage, ist mit GROUP BY stirnrunzelnd?

+1

einen Fehler bekommen, was ist die Logik, die Sie wollen? Sie haben eine Abfrage, die eindeutig nicht funktioniert. Beispieldaten und gewünschte Ergebnisse sind eine große Hilfe. –

+0

Ich möchte alle gefundenen Zeilen von userprofile, wenn Benutzer_id oder connect_to_id in Verbindungstabelle sind wahr und is_connected ist wahr. Die Struktur des Benutzerprofils macht wirklich keinen Unterschied, glaube ich nicht. –

Antwort

1

Es kann entweder über eine join oder einer Unterabfrage erfolgen. Typischerweise sind MySQL-Joins effizienter, da MySQL in vielen Fällen keine Indizes mit Unterabfragen verwenden kann.Also, in Ihrem Fall die Abfrage mit einem Join wäre:

SELECT u.* 
FROM 
    userprofile u 
    JOIN connect c ON (u.user_id = c.user_id OR u.user_id = c.connect_to_id) 
WHERE 
    (c.user_id = '1' OR c.connect_to_id = '1') AND 
    c.is_connected = '1' 
+0

Ich denke, dass ich sehe, was ich mit JOIN vermisste. Also wird die u.user_id in userprofile auf den Wert gesetzt, der nach dem WHERE zurückgegeben wird? –

+0

Und ich nehme an, dass Sie glauben, dass dies die bessere Lösung gegenüber der von Pastor ist wegen der Toleranz gegenüber Fehlern oder gibt es auch eine Geschwindigkeitszunahme? –

+0

Das funktioniert super. Die Syntax von sql passt einfach nicht zu mir. Zum Beispiel ON, ich nehme an, dass das bedeutet, dass ON diesen Parameter auf diese Weise zuordnen? Die WHERE ist offensichtlich und ich habe eine GROUP BY hinzugefügt, die auch Sinn für mich macht. Und danke für die Hilfe @ Unix One –

0

Vielleicht können Sie tun, was Sie wollen exists mit:

SELECT u.* 
FROM userprofile u 
WHERE user_id IN 
     EXISTS (SELECT 1 
       FROM connect c 
       WHERE '1' IN (c.user_id, c.connect_to_id) AND 
        c.is_connected = '1' AND 
        u.user_id IN (c.user_id, c.connect_to_id) 
      ); 

Hinweis: Wenn die IDs numerische Werte sind, dann verwenden Sie keine einfache Anführungszeichen um die Konstanten. Das Mischen von Typen kann den Optimierer verwirren.

+0

Interessanter Gedanke. Ich werde die JOIN-Methode zuerst testen, nur weil ich lese, dass dies der beste Weg ist. Jede Diskussion darüber, welcher Weg aus welchem ​​Grund am besten wäre, wäre großartig. –

1

Ich denke, du bist mit zwei Problemen. Einer von ihnen ist die zwei columns Sache. Der andere ist ein kartesisches Produkt.

Versuchen Sie folgendes:

SELECT * 
    FROM userprofile up 
WHERE up.user_id IN (SELECT connect.user_id 
      FROM connect 
       WHERE connect.connect_to_id = '1' 
       UNION ALL 
       SELECT connect.connect_to_id 
      FROM connect 
       WHERE connect.user_id = '1') 
    AND is_connected = '1' ; 
+0

Ich habe mich gefragt, ob ich zwei Subs verwenden könnte, aber nicht verstanden habe, wie man das schreibt. UNION ALL wäre, was ich vermisst habe. Ich werde dies versuchen und sehen, was passiert. –

0

@Pastor Ich hatte ein Update, um Ihren Code zu tun, wie ich in der is_connected Spaltenprüfsumme

SELECT * 
FROM userprofile up 
    WHERE up.user_id IN (SELECT connect.user_id 
     FROM connect 
      WHERE connect.connect_to_id = '1' AND connect.is_connected = '1' 
     UNION ALL 
     SELECT connect.connect_to_id 
      FROM connect 
       WHERE connect.user_id = '1' AND connect.is_connected = '1')