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'
@ 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'
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
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
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!
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.