it-swarm.com.de

LEFT JOIN nur in der ersten Reihe

Ich habe viele Threads gelesen, in denen es darum geht, nur die erste Zeile eines Links-Joins abzurufen, aber aus irgendeinem Grund funktioniert dies bei mir nicht.

Hier ist meine Struktur (natürlich vereinfacht)

Feeds

id |  title | content
----------------------
1  | Feed 1 | ...

Künstler

artist_id | artist_name
-----------------------
1         | Artist 1
2         | Artist 2

feeds_artists

rel_id | artist_id | feed_id
----------------------------
1      |     1     |    1 
2      |     2     |    1 
...

Jetzt möchte ich die Artikel bekommen und mich nur dem ersten Künstler anschließen, und mir ist so etwas eingefallen:

SELECT *
    FROM feeds 
    LEFT JOIN feeds_artists ON wp_feeds.id = (
        SELECT feeds_artists.feed_id FROM feeds_artists
        WHERE feeds_artists.feed_id = feeds.id 
    LIMIT 1
    )
WHERE feeds.id = '13815'

nur um nur die erste zeile der feeds_artists zu bekommen, aber schon geht das nicht.

Ich kann TOP wegen meiner Datenbank nicht verwenden und ich kann die Ergebnisse nicht nach feeds_artists.artist_id Gruppieren, da ich sie nach Datum sortieren muss (ich habe Ergebnisse erhalten, indem ich sie auf diese Weise gruppiere, aber die Ergebnisse wo nicht das neueste)

Versuchte auch etwas mit OUTER APPLY - auch kein Erfolg. Um ehrlich zu sein, kann ich mir nicht vorstellen, was in diesen Reihen vor sich geht - wahrscheinlich der Hauptgrund, warum ich das nicht zum Laufen bringen kann.

LÖSUNG:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'
121
KddC

@ Matt Dodges Antwort brachte mich auf den richtigen Weg. Nochmals vielen Dank für die Antworten, die inzwischen vielen geholfen haben. Hat es so funktioniert:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'
12
KddC

Wenn Sie davon ausgehen können, dass sich die Künstler-IDs mit der Zeit erhöhen, ist die Funktion MIN(artist_id) die früheste.

Also probiere so etwas aus (ungetestet ...)

SELECT *
  FROM feeds f
  LEFT JOIN artists a ON a.artist_id = (
    SELECT
      MIN(fa.artist_id) a_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.feed_id
  ) a
89
Matt Dodge

Version ohne Unterauswahl:

   SELECT f.title,
          f.content,
          MIN(a.artist_name) artist_name
     FROM feeds f
LEFT JOIN feeds_artists fa ON fa.feed_id = f.id
LEFT JOIN artists a ON fa.artist_id = a.artist_id
 GROUP BY f.id
51

Ich habe etwas anderes benutzt (ich denke besser ...) und möchte es teilen:

Ich habe eine VIEW erstellt, die eine "group" -Klausel enthält

CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code

SELECT * FROM client INNER JOIN vCountries on client_province = province_id

Ich möchte noch sagen, dass ich denke, dass wir diese Lösung brauchen, WEIL WE DID ETWAS FALSCHES IN DER ANALYSE ... zumindest in meinem Fall ... aber manchmal ist es billiger, dies zu tun, um alles neu zu gestalten ...

Ich hoffe, es hilft!

2
Ari Waisberg

Ich möchte eine allgemeinere Antwort geben . Eine, die jeden Fall behandelt , wenn Sie nur das erste Element in einem LEFT JOIN auswählen möchten .

Sie können eine Unterabfrage verwenden, die GROUP_CONCATS ist, was Sie möchten (auch sortiert!). Teilen Sie dann das GROUP_CONCAT-Ergebnis auf und nehmen Sie nur das erste Element wie folgt ...

LEFT JOIN Person ON Person.id = (
    SELECT SUBSTRING_INDEX(
        GROUP_CONCAT(FirstName ORDER BY FirstName DESC SEPARATOR "_" ), '_', 1)
    ) FROM Person
);

Da wir [~ # ~] desc [~ # ~] als unser ORDER BY Option, dies gibt eine Personen ID für jemanden wie "Zack" zurück. Wenn wir jemanden mit dem Namen "Andy" wollen, ändern wir ORDER BY FirstName DESC zu ORDER BY FirstName ASC .

Dies ist flink, da Sie die Macht der Bestellung ganz in Ihre Hände legen. Aber nach vielen Tests wird es in einer Situation mit vielen Benutzern und vielen Daten nicht gut skaliert .

Es ist jedoch nützlich, um datenintensive Berichte für den Administrator auszuführen.

1
HoldOffHunger