96 votes

MySQL JOIN avec LIMIT 1 sur la table jointe

Je veux joindre deux tables, mais obtenir seulement un enregistrement de la table 2 par enregistrement de la table 1.

Par exemple :

SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id

Cela me permettrait d'avoir tous les enregistrements dans products ce qui n'est pas ce que je veux. Je veux 1 [le premier] produit par catégorie (j'ai une catégorie de produits). sort dans le champ des produits).

Comment dois-je m'y prendre ?

0voto

Mchl Points 32343

En supposant que vous voulez un produit avec MIN() valeur essentielle dans sort colonne, cela ressemblerait à quelque chose comme ceci.

SELECT 
  c.id, c.title, p.id AS product_id, p.title
FROM 
  categories AS c
INNER JOIN (
  SELECT
    p.id, p.category_id, p.title
  FROM
    products AS p
  CROSS JOIN (
    SELECT p.category_id, MIN(sort) AS sort
    FROM products
    GROUP BY category_id
  ) AS sq USING (category_id)
) AS p ON c.id = p.category_id

0voto

Alan Points 417

Un autre exemple avec 3 tables imbriquées : 1/ Utilisateur 2/ UserRoleCompanie 3/ Compagnie

  • 1 utilisateur a plusieurs UserRoleCompanie.
  • 1 UserRoleCompanie a 1 utilisateur et 1 Company
  • 1 Companie a plusieurs UserRoleCompanie

    SELECT u.id as userId, u.firstName, u.lastName, u.email, urc.id , urc.companieRole, c.id as companieId, c.name as companieName FROM User as u JOIN UserRoleCompanie as urc ON u.id = urc.userId AND urc.id = ( SELECT urc2.id FROM UserRoleCompanie urc2 JOIN Companie ON urc2.companieId = Companie.id AND urc2.userId = u.id AND Companie.isPersonal = false order by Companie.createdAt DESC

        limit 1
    )

    LEFT JOIN Companie as c ON urc.companieId = c.id

    +---------------------------+-----------+--------------------+---------------------------+---------------------------+--------------+---------------------------+-------------------+ | userId | firstName | lastName | email | id | companieRole | companieId | companieName | +---------------------------+-----------+--------------------+---------------------------+---------------------------+--------------+---------------------------+-------------------+ | cjjt9s9iw037f0748raxmnnde | henry | pierrot | henry@gmail.com | cjtuflye81dwt0748e4hnkiv0 | OWNER | cjtuflye71dws0748r7vtuqmg | leclerc |

0voto

À mon avis, c'est la meilleure réponse (en la rendant générale) :

SELECT  
TB1.Id  
FROM Table1 AS TB1  
INNER JOIN Table2 AS TB2 ON (TB1.Id = TB2.Id_TB1)  
    AND TB2.Id = (  
        SELECT Id  
        FROM Table2  
        WHERE TB1.Id = Id_TB1  
        ORDER BY Table2.Id DESC  
        LIMIT 1  
    )

-1voto

Yaki Klein Points 2574

Lorsque vous utilisez postgres, vous pouvez utiliser l'option DISTINCT ON syntex pour limiter le nombre de colonnes renvoyées par l'une ou l'autre des tables.

Voici un exemple de code :

SELECT c.id, c.title, p.id AS product_id, p.title FROM categories AS c JOIN ( SELECT DISTINCT ON(p1.id) id, p1.title, p1.category_id FROM products p1 ) p ON (c.id = p.category_id)
L'astuce consiste à ne pas joindre directement la table contenant plusieurs occurrences de l'identifiant, mais plutôt à créer une table contenant une seule occurrence pour chaque identifiant.

-3voto

Matías Points 1

Remplacez les tables par les vôtres :

SELECT * FROM works w 
LEFT JOIN 
(SELECT photoPath, photoUrl, videoUrl FROM workmedias LIMIT 1) AS wm ON wm.idWork = w.idWork

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X