web-dev-qa-db-fra.com

LEFT JOIN seulement la première rangée

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'
121
KddC

@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'
12
KddC

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
89
Matt Dodge

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
51
Denis Khvorostin

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!

2
Ari Waisberg

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.

1
HoldOffHunger