Tous les produits
Search
Centre de documentation

MaxCompute:JOIN

Dernière mise à jour :Aug 21, 2026

MaxCompute vous permet d'utiliser des opérations JOIN pour joindre des tables et renvoyer les données qui satisfont aux conditions de jointure et de requête. Cette rubrique décrit les opérations JOIN suivantes : LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, INNER JOIN, NATURAL JOIN, jointure implicite et jointures multiples.

Présentation

MaxCompute prend en charge les types d'opérations JOIN suivants :

  • LEFT OUTER JOIN

    Également appelée LEFT JOIN. L'opération LEFT OUTER JOIN renvoie toutes les lignes de la table de gauche, y compris celles qui ne correspondent à aucune ligne de la table de droite.

    Remarque

    Dans une opération JOIN, la table de gauche est généralement une grande table et la table de droite une petite table. Si certaines valeurs de la table de droite sont dupliquées, nous vous déconseillons d'exécuter plusieurs opérations LEFT JOIN consécutives. En effet, cela peut provoquer une膨胀 des données (data bloat) et entraîner l'interruption de vos tâches. Si vous exécutez plusieurs opérations LEFT JOIN consécutives, une膨胀 des données peut se produire et vos tâches peuvent être interrompues.

  • RIGHT OUTER JOIN

    Également appelée RIGHT JOIN. L'opération RIGHT OUTER JOIN renvoie toutes les lignes de la table de droite, y compris celles qui ne correspondent à aucune ligne de la table de gauche.

  • FULL OUTER JOIN

    Également appelée FULL JOIN. L'opération FULL OUTER JOIN renvoie toutes les lignes des tables de gauche et de droite.

  • INNER JOIN

    Le mot-clé INNER peut être omis. L'opération INNER JOIN renvoie les lignes de données lorsqu'une correspondance existe entre les tables de gauche et de droite.

  • NATURAL JOIN

    Lors d'une opération NATURAL JOIN, les champs utilisés pour joindre deux tables sont déterminés en fonction des champs communs aux deux tables. MaxCompute prend en charge l'opération OUTER NATURAL JOIN. Si vous utilisez la clause USING, l'opération NATURAL JOIN ne renvoie les champs communs qu'une seule fois.

  • Jointure implicite

    Vous pouvez exécuter une opération JOIN implicite sans avoir besoin de spécifier le mot-clé JOIN.

  • Jointures multiples

    MaxCompute prend en charge plusieurs opérations JOIN. Vous pouvez utiliser des parenthèses () pour spécifier les priorités des opérations JOIN. Une opération JOIN placée entre parenthèses () possède une priorité plus élevée.

Remarque
  • Si une instruction SQL contient la clause WHERE et que vous utilisez la clause JOIN avant la clause WHERE, l'opération JOIN est effectuée en premier. Ensuite, les résultats obtenus par l'opération JOIN sont filtrés selon les conditions spécifiées par la clause WHERE. Le résultat final correspond à l'intersection des deux tables, et non à toutes les lignes d'une table.

  • Vous pouvez utiliser le paramètre odps.task.sql.outerjoin.ppd pour contrôler si une condition non liée à la jointure dans la clause OUTER JOIN ON doit être utilisée comme donnée d'entrée de l'opération JOIN. Vous pouvez configurer ce paramètre au niveau du projet ou de la session.

    • Si vous définissez ce paramètre sur false, la condition non liée à la jointure dans la clause ON est considérée comme une condition de la clause WHERE pour la sous-requête de l'opération JOIN. Ce comportement n'est pas standard. Nous vous recommandons de spécifier la condition non liée à la jointure dans la clause WHERE.

    • Si vous définissez ce paramètre sur false, les instructions SQL suivantes sont équivalentes. Si vous le définissez sur true, les deux instructions SQL ne sont pas équivalentes.

    SELECT A.*, B.* FROM A LEFT JOIN B ON A.c1 = B.c1 and A.c2='xxx';
    
    SELECT A.*, B.* FROM (SELECT * FROM A WHERE c2='xxx') A LEFT JOIN B ON A.c1 = B.c1;

Remarques d'utilisation

Lors d'une opération JOIN, la condition de filtre key is not null de l'opération JOIN est automatiquement ajoutée pour le calcul. La ligne dont la valeur de la clé de jointure est nulle est filtrée après l'opération JOIN.

Limites

Lorsque vous exécutez une opération JOIN, tenez compte des limites suivantes :

  • MaxCompute ne prend pas en charge l'opération CROSS JOIN. Une opération CROSS JOIN joint deux tables sans qu'il soit nécessaire de spécifier des conditions dans la clause ON.

  • Vous devez utiliser des jointures par égalité et combiner les conditions à l'aide de AND. Vous pouvez utiliser des jointures par inégalité ou combiner plusieurs conditions à l'aide de OR dans une opération MAPJOIN. Pour plus d'informations, consultez la section MAPJOIN.

Syntaxe

<table_reference> JOIN <table_factor> [<join_condition>]
| <table_reference> {LEFT OUTER|RIGHT OUTER|FULL OUTER|INNER|NATURAL} JOIN <table_reference> <join_condition>
  • table_reference : obligatoire. L'instruction de requête pour la table de gauche sur laquelle l'opération JOIN est effectuée. La valeur de ce paramètre est au format table_name [alias] | table_query [alias] |....

  • table_factor : obligatoire. L'instruction de requête pour la table de droite ou une table sur laquelle l'opération JOIN est effectuée. La valeur de ce paramètre est au format table_name [alias] | table_subquery [alias] |....

  • join_condition : facultatif. Une condition JOIN est une combinaison d'une ou plusieurs expressions d'égalité. La valeur de ce paramètre est au format on equality_expression [and equality_expression].... equality_expression représente une expression d'égalité.

Remarque

Si des conditions d'élimination de partitions sont spécifiées dans la clause WHERE, l'élimination de partitions s'applique à la fois aux tables parentes et enfants. Si des conditions d'élimination de partitions sont spécifiées dans la clause ON, l'élimination de partitions s'applique uniquement à la table enfant. Par conséquent, une analyse complète de la table (full table scan) est effectuée pour la table parente. Pour plus d'informations, consultez la section Évaluer l'efficacité de l'élimination de partitions.

Données d'exemple

Des données source d'exemple sont fournies pour vous aider à mieux comprendre les exemples de cette rubrique. Les instructions suivantes montrent comment créer les tables sale_detail et sale_detail_jt et y insérer des données.

-- Create two partitioned tables named sale_detail and sale_detail_jt. 
CREATE TABLE if NOT EXISTS sale_detail
(
shop_name     STRING,
customer_id   STRING,
total_price   DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);

CREATE TABLE if NOT EXISTS sale_detail_jt
(
shop_name     STRING,
customer_id   STRING,
total_price   DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);

-- Add partitions to the two tables. 
ALTER TABLE sale_detail ADD PARTITION (sale_date='2013', region='china') PARTITION (sale_date='2014', region='shanghai');
ALTER TABLE sale_detail_jt ADD PARTITION (sale_date='2013', region='china');

-- Insert data into the tables. 
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);
INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai') VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);
INSERT INTO sale_detail_jt PARTITION (sale_date='2013', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s5','c2',100.2);

-- Query data from the sale_detail and sale_detail_jt tables. Sample statements:
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;
-- The following result is returned:
+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
| s3         | c3          | 100.3       | 2013       | china      |
| null       | c5          | NULL        | 2014       | shanghai   |
| s6         | c6          | 100.4       | 2014       | shanghai   |
| s7         | c7          | 100.5       | 2014       | shanghai   |
+------------+-------------+-------------+------------+------------+

SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail_jt;
-- The following result is returned:
+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
| s5         | c2          | 100.2       | 2013       | china      |
+------------+-------------+-------------+------------+------------+

-- Create a table for the JOIN operation. 
SET odps.sql.allow.fullscan=true;
CREATE TABLE shop AS SELECT shop_name, customer_id, total_price FROM sale_detail;

Exemples

Les exemples suivants illustrent l'utilisation de JOIN sur la base des données d'exemple.

  • Exemple 1 : LEFT OUTER JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. 
    SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a 
           LEFT OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;

    Le résultat suivant est renvoyé :

    +------------+------------+
    | ashop      | bshop      |
    +------------+------------+
    | s2         | s2         |
    | s1         | s1         |
    | s5         | NULL       |
    +------------+------------+
  • Exemple 2 : RIGHT OUTER JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. 
    SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a 
           RIGHT OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;

    Le résultat suivant est renvoyé :

    +------------+------------+
    | ashop      | bshop      |
    +------------+------------+
    | s1         | s1         |
    | s2         | s2         |
    | NULL       | s3         |
    | NULL       | null       |
    | NULL       | s6         |
    | NULL       | s7         |
    +------------+------------+
  • Exemple 3 : FULL OUTER JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. 
    SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a 
           FULL OUTER JOIN sale_detail b ON a.shop_name=b.shop_name;

    Le résultat suivant est renvoyé :

    +------------+------------+
    | ashop      | bshop      |
    +------------+------------+
    | NULL       | s3         |
    | NULL       | s6         |
    | s2         | s2         |
    | NULL       | null       |
    | NULL       | s7         |
    | s1         | s1         |
    | s5         | NULL       |
    +------------+------------+
  • Exemple 4 : INNER JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. 
    SELECT a.shop_name AS ashop, b.shop_name AS bshop FROM sale_detail_jt a 
           INNER JOIN sale_detail b ON a.shop_name=b.shop_name;

    Le résultat suivant est renvoyé :

    +------------+------------+
    | ashop      | bshop      |
    +------------+------------+
    | s2         | s2         |
    | s1         | s1         |
    +------------+------------+
  • Exemple 5 : NATURAL JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Perform a NATURAL JOIN operation. 
    SELECT * FROM sale_detail_jt NATURAL JOIN sale_detail;
    -- The preceding statement is equivalent to the following statement: 
    SELECT sale_detail_jt.shop_name AS shop_name, sale_detail_jt.customer_id AS customer_id, sale_detail_jt.total_price AS total_price, sale_detail_jt.sale_date as sale_date, sale_detail_jt.region as region from sale_detail_jt 
    INNER JOIN sale_detail 
    ON sale_detail_jt.shop_name=sale_detail.shop_name AND sale_detail_jt.customer_id=sale_detail.customer_id and sale_detail_jt.total_price=sale_detail.total_price AND sale_detail_jt.sale_date=sale_detail.sale_date AND sale_detail_jt.region=sale_detail.region;

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s1         | c1          | 100.1       | 2013       | china      |
    | s2         | c2          | 100.2       | 2013       | china      |
    +------------+-------------+-------------+------------+------------+
  • Exemple 6 : jointure implicite. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Perform an implicit JOIN operation. 
    SELECT * FROM sale_detail_jt, sale_detail WHERE sale_detail_jt.shop_name = sale_detail.shop_name;
    -- The preceding statement is equivalent to the following statement: 
    SELECT * FROM sale_detail_jt JOIN sale_detail ON sale_detail_jt.shop_name = sale_detail.shop_name;

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     | shop_name2 | customer_id2 | total_price2 | sale_date2 | region2    |
    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+
    | s2         | c2          | 100.2       | 2013       | china      | s2         | c2           | 100.2        | 2013       | china      |
    | s1         | c1          | 100.1       | 2013       | china      | s1         | c1           | 100.1        | 2013       | china      |
    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+
  • Exemple 7 : jointures multiples. Aucune priorité n'est spécifiée. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Both the sale_detail_jt and sale_detail tables have the shop_name column. You must use aliases to distinguish between the columns in the SELECT statement. 
    SELECT a.* FROM sale_detail_jt a FULL OUTER JOIN sale_detail b ON a.shop_name=b.shop_name
            FULL OUTER JOIN sale_detail c ON a.shop_name=c.shop_name;

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s5         | c2          | 100.2       | 2013       | china      |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | s1         | c1          | 100.1       | 2013       | china      |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    | s2         | c2          | 100.2       | 2013       | china      |
    | NULL       | NULL        | NULL        | NULL       | NULL       |
    +------------+-------------+-------------+------------+------------+
  • Exemple 8 : jointures multiples. Utilisez des parenthèses () pour spécifier les priorités des opérations JOIN. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Perform multiple JOIN operations. Use parentheses () to specify the priority. 
    SELECT * FROM shop JOIN (sale_detail_jt JOIN sale_detail ON sale_detail_jt.shop_name = sale_detail.shop_name) ON shop.shop_name=sale_detail_jt.shop_name;

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     | shop_name2 | customer_id2 | total_price2 | sale_date2 | region2    | shop_name3 | customer_id3 | total_price3 | sale_date3 | region3    |
    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+
    | s2         | c2          | 100.2       | 2013       | china      | s2         | c2           | 100.2        | 2013       | china      | s2         | c2           | 100.2        | 2013       | china      |
    | s1         | c1          | 100.1       | 2013       | china      | s1         | c1           | 100.1        | 2013       | china      | s1         | c1           | 100.1        | 2013       | china      |
    +------------+-------------+-------------+------------+------------+------------+--------------+--------------+------------+------------+------------+--------------+--------------+------------+------------+
  • Exemple 9 : Utilisez JOIN et WHERE pour interroger le nombre d'enregistrements dont la région est « china » et dont le champ shop_name a la même valeur dans les deux tables. Tous les enregistrements de la table sale_detail sont conservés. Instructions d'exemple :

    -- The full table scan feature must be enabled for partitioned tables. Otherwise, the JOIN operation fails. 
    SET odps.sql.allow.fullscan=true;
    -- Execute the following SQL statement: 
    SELECT a.shop_name
        ,a.customer_id
        ,a.total_price
            ,b.total_price 
    FROM  (SELECT * FROM sale_detail WHERE region = "china") a 
    LEFT JOIN (SELECT * FROM sale_detail_jt WHERE region = "china") b 
    ON   a.shop_name = b.shop_name;

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+--------------+
    | shop_name  | customer_id | total_price | total_price2 |
    +------------+-------------+-------------+--------------+
    | s1         | c1          | 100.1       | 100.1        |
    | s2         | c2          | 100.2       | 100.2        |
    | s3         | c3          | 100.3       | NULL         |
    +------------+-------------+-------------+--------------+

    Instruction d'exemple illustrant une utilisation incorrecte :

    SELECT a.shop_name
        ,a.customer_id
        ,a.total_price
            ,b.total_price 
    FROM  sale_detail a 
    LEFT JOIN sale_detail_jt b 
    ON   a.shop_name = b.shop_name 
    WHERE  a.region = "china" AND b.region = "china";

    Le résultat suivant est renvoyé :

    +------------+-------------+-------------+--------------+
    | shop_name  | customer_id | total_price | total_price2 |
    +------------+-------------+-------------+--------------+
    | s1         | c1          | 100.1       | 100.1        |
    | s2         | c2          | 100.2       | 100.2        |
    +------------+-------------+-------------+--------------+

    Le résultat renvoyé correspond à l'intersection des deux tables, et non à toutes les lignes de la table sale_detail.