J'ai lu beaucoup de discussions sur le fait d'obtenir uniquement la première ligne d'une jointure gauche, mais pour une raison quelconque, cela ne fonctionne pas pour moi.
Voici ma structure (simplifiée bien sûr)
Flux
id | title | content
----------------------
1 | Feed 1 | ...
Artistes
artist_id | artist_name
-----------------------
1 | Artist 1
2 | Artist 2
feeds_artists
rel_id | artist_id | feed_id
----------------------------
1 | 1 | 1
2 | 2 | 1
...
Maintenant, je veux obtenir les articles et ne rejoindre que le premier artiste et j'ai pensé à quelque chose comme ceci:
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'
juste pour obtenir uniquement la première ligne de feeds_artists, mais cela ne fonctionne déjà pas.
Je ne peux pas utiliser TOP
à cause de ma base de données et je ne peux pas regrouper les résultats par feeds_artists.artist_id
car je dois les trier par date (j'ai obtenu les résultats en les regroupant de cette façon, mais le plus récent)
Essayé quelque chose avec OUTER APPLY aussi - pas de succès aussi. Pour être honnête, je ne peux pas vraiment imaginer ce qui se passe dans ces rangées - probablement la principale raison pour laquelle je ne peux pas obtenir que cela fonctionne.
SOLUTION:
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 répond, mets-moi sur la bonne voie. Merci encore pour toutes les réponses, qui ont aidé beaucoup de gars entre-temps. Je l'ai eu comme ça:
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'
Si vous pouvez supposer que les ID d’artiste s’incrémentent dans le temps, la MIN(artist_id)
sera la plus ancienne.
Alors essayez quelque chose comme ça (non testé ...)
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 sans sous-sélection:
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
J'ai utilisé quelque chose d'autre (je pense mieux ...) et je veux le partager:
J'ai créé une vue qui a une clause "group"
CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code
SELECT * FROM client INNER JOIN vCountries on client_province = province_id
Je tiens à dire encore que je pense que nous devons faire cette solution PARCE QUE WE DID quelque chose qui ne va pas dans l'analyse ... du moins dans mon cas ... mais parfois moins cher de faire cela que de tout refaire ...
J'espère que ça aide!
Je veux donner plus réponse généralisée. Un qui gérera dans tous les cas, lorsque vous voulez sélectionner uniquement le premier élément d'un JOIN GAUCHE.
Vous pouvez utiliser une sous-requête qui donne à GROUP_CONCATS ce que vous voulez (trié aussi!), Puis divisez le résultat de GROUP_CONCAT et ne prenez que son premier élément, comme suit ...
LEFT JOIN Person ON Person.id = (
SELECT SUBSTRING_INDEX(
GROUP_CONCAT(FirstName ORDER BY FirstName DESC SEPARATOR "_" ), '_', 1)
) FROM Person
);
Puisque nous avons DESC comme notre option ORDER BY, cela retournera un identifiant de personne pour quelqu'un comme "Zack". Si nous voulions quelqu'un avec le nom comme "Andy", nous changerions ORDER BY FirstName DESC en ORDER BY FirstName ASC.
C'est agile, car cela met le pouvoir de commander totalement entre vos mains. Mais, après de nombreux tests, l’échelle ne fonctionnera pas bien dans une situation avec beaucoup d’utilisateurs et beaucoup de données.
Cependant, il est utile pour exécuter des rapports intensifs en données pour admin.