Todos os produtos
Search
Central de documentação

MaxCompute:Sintaxe SELECT

Última atualização: Jun 27, 2026

Instruções SELECT consultam dados em tabelas. Este tópico aborda a sintaxe completa do SELECT no MaxCompute, incluindo cláusulas para filtragem, agrupamento, ordenação e distribuição de dados.

Antes de executar instruções SELECT, verifique se você tem a permissão Select na tabela de destino. Para mais informações, consulte Permissões do MaxCompute.

Plataformas suportadas:

Operações de consulta

As instruções SELECT suportam as seguintes operações de consulta.

Operação

Descrição

Subconsultas

Executam consultas adicionais com base no resultado de uma consulta anterior

INTERSECT, UNION e EXCEPT

Obtêm a interseção, união ou conjunto complementar de dois conjuntos de dados

JOIN

Unem tabelas com base em condições de junção e consulta

SEMI JOIN

Filtram dados da tabela esquerda usando a tabela direita; retornam apenas dados presentes na tabela esquerda

MAPJOIN HINT

Especificam dicas MAPJOIN para otimizar o desempenho de JOIN em uma tabela grande e uma ou mais tabelas pequenas

SKEWJOIN HINT

Tratam valores de chave quente e problemas de longa cauda em operações JOIN

Lateral View

Usam LATERAL VIEW com uma função de valor de tabela definida pelo usuário (UDTF) para dividir uma linha em várias linhas

GROUPING SETS

Agregam e analisam dados em múltiplas dimensões

SELECT TRANSFORM

Iniciam um subprocesso e usam entrada/saída padrão para E/S de dados

Dica Split Size

Modificam o tamanho da divisão para controlar o paralelismo das subtarefas

Consultas time travel e incrementais

Consultam dados históricos (time travel) ou dados incrementais históricos em tabelas Delta

Limitações

  • Exibição de resultados SELECT: É possível exibir no máximo 10.000 linhas, e o tamanho do resultado retornado deve ser inferior a 10 MB. Esse limite não se aplica a cláusulas SELECT usadas dentro de consultas maiores — estas retornam todos os resultados para a camada superior.

  • Varredura completa em tabelas particionadas: Projetos criados após as 20:00:00 de 10 de janeiro de 2018 não podem realizar varredura completa em tabelas particionadas. Sempre especifique as partições a serem verificadas. Essa prática reduz E/S desnecessária, conserva recursos de computação e diminui custos no modelo de pagamento conforme o uso. Para ativar a varredura completa em uma consulta específica, execute SET odps.sql.allow.fullscan=true; junto com a consulta no mesmo commit:

    SET odps.sql.allow.fullscan=true;
    SELECT * FROM sale_detail;
  • Poda de buckets em tabelas clusterizadas: A poda de buckets só entra em vigor quando uma única varredura de tabela abrange 400 partições ou menos. Quando a poda não se aplica, mais dados são verificados — o que aumenta os custos no modelo de pagamento conforme o uso e degrada o desempenho no modelo de assinatura.

Sintaxe

[WITH <cte>[, ...] ]
SELECT [ALL | DISTINCT] <SELECT_expr>[, <EXCEPT_expr>][, <REPLACE_expr>] ...
       FROM <TABLE_reference>
       [WHERE <WHERE_condition>]
       [GROUP BY {<col_list>|ROLLUP(<col_list>)}]
       [HAVING <HAVING_condition>]
       [WINDOW <WINDOW_clause>]
       [ORDER BY <ORDER_condition>]
       [DISTRIBUTE BY <DISTRIBUTE_condition> [SORT BY <SORT_condition>]|[ CLUSTER BY <CLUSTER_condition>] ]
       [LIMIT <number>]

Para saber a ordem de execução das cláusulas, consulte Sequência de execução de cláusulas em uma instrução SELECT.

Dados de exemplo

Os exemplos deste tópico utilizam a tabela sale_detail. Execute as instruções abaixo para criar a tabela e inserir dados de exemplo:

-- Create a partitioned table named sale_detail.
CREATE TABLE IF NOT EXISTS sale_detail
(
shop_name     STRING,
customer_id   STRING,
total_price   DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);

-- Add a partition.
ALTER TABLE sale_detail ADD PARTITION (sale_date='2013', region='china');

-- Insert sample data.
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china') VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);

Consulte todas as colunas para confirmar os dados:

SELECT * FROM sale_detail;

Resultado:

+------------+-------------+-------------+------------+------------+
| 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      |
+------------+-------------+-------------+------------+------------+

Cláusula WITH (CTE)

A cláusula WITH define uma ou mais expressões de tabela comuns (CTEs) como tabelas temporárias que consultas subsequentes podem referenciar.

Regras:

  • Os nomes das CTEs devem ser únicos dentro de uma cláusula WITH.

  • Uma CTE só pode referenciar outras CTEs definidas na mesma cláusula WITH — não pode referenciar a si mesma nem formar ciclos.

Autorreferência recursiva (inválida):

WITH
A AS (SELECT 1 FROM A)
SELECT * FROM A;

Erro:

FAILED: ODPS-0130161:[1,6] Parse exception - recursive cte A is invalid, it must have an initial_part and a recursive_part, which must be connected by UNION ALL

Referência circular (inválida):

WITH
A AS (SELECT * FROM B),
B AS (SELECT * FROM A)
SELECT * FROM B;

Erro:

FAILED: ODPS-0130071:[1,26] Semantic analysis exception - while resolving view B - [1,51]recursive function call is not supported, cycle is A->B->A

Uso válido:

WITH
A AS (SELECT 1 AS C),
B AS (SELECT * FROM A)
SELECT * FROM B;

Resultado:

+---+
| c |
+---+
| 1 |
+---+

Expressão de coluna (SELECT_expr)

SELECT_expr (obrigatório) especifica as colunas ou expressões a serem retornadas. O formato é col1_name, col2_name, expressão de coluna, ....

Especificar nomes de colunas

Leia colunas específicas pelo nome:

SELECT shop_name FROM sale_detail;

Resultado:

+------------+
| shop_name  |
+------------+
| s1         |
| s2         |
| s3         |
+------------+

Usar * para todas as colunas

* seleciona todas as colunas. Combine com WHERE para filtrar:

-- Full table scan must be explicitly enabled for partitioned tables.
SET odps.sql.allow.fullscan=true;
SELECT * FROM sale_detail;

Resultado:

+------------+-------------+-------------+------------+------------+
| 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      |
+------------+-------------+-------------+------------+------------+

Com um filtro WHERE:

SELECT * FROM sale_detail WHERE shop_name='s1';

Resultado:

+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
+------------+-------------+-------------+------------+------------+

Usar expressões regulares

Envolva uma expressão regular entre crases para corresponder a nomes de colunas. O conteúdo entre crases é interpretado como um padrão regex, não como um nome de coluna — esta é uma sintaxe específica do MaxCompute.

Selecione todas as colunas cujos nomes começam com sh:

SELECT `sh.*` FROM sale_detail;

Resultado:

+------------+
| shop_name  |
+------------+
| s1         |
| s2         |
| s3         |
+------------+

Exclua shop_name (selecione todas as outras colunas):

SELECT `(shop_name)?+.+` FROM sale_detail;

Resultado:

+-------------+-------------+------------+------------+
| customer_id | total_price | sale_date  | region     |
+-------------+-------------+------------+------------+
| c1          | 100.1       | 2013       | china      |
| c2          | 100.2       | 2013       | china      |
| c3          | 100.3       | 2013       | china      |
+-------------+-------------+------------+------------+

Exclua múltiplas colunas (shop_name e customer_id):

SELECT `(shop_name|customer_id)?+.+` FROM sale_detail;

Resultado:

+-------------+------------+------------+
| total_price | sale_date  | region     |
+-------------+------------+------------+
| 100.1       | 2013       | china      |
| 100.2       | 2013       | china      |
| 100.3       | 2013       | china      |
+-------------+------------+------------+

Exclua todas as colunas cujos nomes começam com t:

SELECT `(t.*)?+.+` FROM sale_detail;

Resultado:

+------------+-------------+------------+------------+
| shop_name  | customer_id | sale_date  | region     |
+------------+-------------+------------+------------+
| s1         | c1          | 2013       | china      |
| s2         | c2          | 2013       | china      |
| s3         | c3          | 2013       | china      |
+------------+-------------+------------+------------+
Ao excluir múltiplas colunas em que um nome é prefixo de outro, coloque o nome mais longo primeiro. Por exemplo, para excluir tanto ds quanto dshh , use ` (dshhds)?+.+ — não (dsdshh)?+.+ `.

Usar DISTINCT e ALL

DISTINCT remove linhas duplicadas. ALL (o padrão) retorna todas as linhas, incluindo duplicatas.

Retorne valores distintos de region:

SELECT DISTINCT region FROM sale_detail;

Resultado:

+------------+
| region     |
+------------+
| china      |
+------------+

Quando DISTINCT é aplicado a múltiplas colunas, a deduplicação ocorre com base na combinação de todas as colunas especificadas:

SELECT DISTINCT region, sale_date FROM sale_detail;

Resultado:

+------------+------------+
| region     | sale_date  |
+------------+------------+
| china      | 2013       |
+------------+------------+

É possível usar DISTINCT com funções de janela para deduplicar os resultados calculados:

SET odps.sql.allow.fullscan=true;
SELECT DISTINCT sale_date, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total_price) AS rn FROM sale_detail;

Resultado:

+-----------+------------+
| sale_date | rn         |
+-----------+------------+
| 2013      | 1          |
+-----------+------------+
Não é possível usar DISTINCT com GROUP BY . A instrução a seguir retorna um erro:
SELECT DISTINCT shop_name FROM sale_detail GROUP BY shop_name;
-- Error: GROUP BY cannot be used with SELECT DISTINCT

Exclusão de colunas (EXCEPT)

EXCEPT (opcional) exclui colunas específicas ao ler todas as demais. Formato: EXCEPT(col1_name, col2_name, ...).

Leia todas as colunas exceto region:

SELECT * EXCEPT(region) FROM sale_detail;

Resultado:

+-----------+-------------+-------------+-----------+
| shop_name | customer_id | total_price | sale_date |
+-----------+-------------+-------------+-----------+
| s1        | c1          | 100.1       | 2013      |
| s2        | c2          | 100.2       | 2013      |
| s3        | c3          | 100.3       | 2013      |
+-----------+-------------+-------------+-----------+

Modificação de colunas (REPLACE)

REPLACE (opcional) substitui colunas especificadas por resultados de expressões, mantendo as demais inalteradas. Formato: REPLACE(exp1 [AS] col1_name, exp2 [AS] col2_name, ...).

Leia todas as colunas, substituindo total_price por total_price + 100 e region por uma string fixa:

SELECT * REPLACE(total_price+100 AS total_price, 'shanghai' AS region) FROM sale_detail;

Resultado:

+-----------+-------------+-------------+-----------+--------+
| shop_name | customer_id | total_price | sale_date | region |
+-----------+-------------+-------------+-----------+--------+
| s1        | c1          | 200.1       | 2013      | shanghai |
| s2        | c2          | 200.2       | 2013      | shanghai |
| s3        | c3          | 200.3       | 2013      | shanghai |
+-----------+-------------+-------------+-----------+--------+

Referência de tabela (TABLE_reference)

TABLE_reference (obrigatório) especifica a tabela a ser consultada.

Consulte uma tabela pelo nome:

SELECT customer_id FROM sale_detail;

Resultado:

+-------------+
| customer_id |
+-------------+
| c1          |
| c2          |
| c3          |
+-------------+

Use uma subconsulta aninhada como source da tabela:

SELECT * FROM (SELECT region,sale_date FROM sale_detail) t WHERE region = 'china';

Resultado:

+------------+------------+
| region     | sale_date  |
+------------+------------+
| china      | 2013       |
| china      | 2013       |
| china      | 2013       |
+------------+------------+

Cláusula WHERE

WHERE (opcional) filtra linhas. Em tabelas particionadas, especificar colunas de partição no WHERE ativa a poda de partições, reduzindo a quantidade de dados verificados.

Operadores relacionais suportados:

  • >, <, =, >=, <=, <>

  • LIKE, RLIKE

  • IN, NOT IN

  • BETWEEN...AND

Para mais informações, consulte Operadores relacionais.

Filtre por intervalo de partição para evitar varredura completa da tabela:

SELECT *
FROM sale_detail
WHERE sale_date >= '2008' AND sale_date <= '2014';
-- Equivalent to:
SELECT *
FROM sale_detail
WHERE sale_date BETWEEN '2008' AND '2014';

Resultado:

+------------+-------------+-------------+------------+------------+
| 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      |
+------------+-------------+-------------+------------+------------+
Use a instrução EXPLAIN para verificar se a poda de partições está funcionando. UDFs ou condições JOIN podem impedir a poda. Para detalhes, consulte Verificar se a poda de partições é eficaz .

Alias de coluna no WHERE

Não é possível referenciar no WHERE um alias de coluna definido por meio de uma função. A instrução a seguir retorna um erro:

SELECT  task_name
        ,inst_id
        ,settings
        ,GET_JSON_OBJECT(settings, '$.SKYNET_ID') AS skynet_id
        ,GET_JSON_OBJECT(settings, '$.SKYNET_NODENAME') AS user_agent
FROM    Information_Schema.TASKS_HISTORY
WHERE   ds = '20211215' AND skynet_id IS NOT NULL
LIMIT 10;

Poda de partições baseada em UDF

Ao usar UDFs em cláusulas WHERE, o MaxCompute pode executá-las como pequenos jobs para determinar intervalos de partição. Dois métodos estão disponíveis:

Método 1: Anotar a classe UDF

Adicione a seguinte anotação à sua classe UDF:

@com.aliyun.odps.udf.annotation.UdfProperty(isDeterministic=true)
A anotação com.aliyun.odps.udf.annotation.UdfProperty requer a versão 0.30.X ou posterior do odps-sdk-udf.

Método 2: Usar um comando SET

SET odps.sql.udf.ppr.deterministic = true;

Isso trata todas as UDFs na instrução como determinísticas. Até 1.000 partições podem ser preenchidas retroativamente. Para suprimir erros quando mais de 1.000 partições forem afetadas (e desativar a poda baseada em UDF):

SET odps.sql.udf.ppr.to.subquery = false;

Requisito de posicionamento: A UDF deve aparecer na cláusula WHERE da consulta à tabela de source. Colocá-la em uma condição JOIN ON não aciona a poda.

Correto:

-- UDF in the WHERE clause of the source table query.
SELECT key, value FROM srcp WHERE udf(ds) = 'xx';

Incorreto (UDF no JOIN ON — a poda não se aplica):

SELECT A.c1, A.c2 FROM srcp1 A JOIN srcp2 B ON A.c1 = B.c1 AND udf(A.ds) ='xx';

GROUP BY

GROUP BY (opcional) agrupa linhas por colunas ou expressões especificadas, geralmente usado com funções de agregação.

Regras:

  • O GROUP BY é avaliado antes do SELECT. As referências de coluna no GROUP BY podem ser nomes de colunas da tabela de entrada, expressões ou aliases de colunas de saída do SELECT.

  • Todas as colunas não agregadas no SELECT devem aparecer no GROUP BY.

  • Se as colunas no GROUP BY forem especificadas por uma expressão regular, use a expressão completa.

Agrupe pelo nome da coluna:

SELECT region FROM sale_detail GROUP BY region;

Resultado:

+------------+
| region     |
+------------+
| china      |
+------------+

Agrupe pelo nome da coluna com agregação:

SELECT region, SUM(total_price) FROM sale_detail GROUP BY region;

Resultado:

+------------+------------+
| region     | _c1        |
+------------+------------+
| china      | 300.6      |
+------------+------------+

Agrupe pelo alias da coluna de saída:

SELECT region AS r FROM sale_detail GROUP BY r;
-- Equivalent to:
SELECT region AS r FROM sale_detail GROUP BY region;

Resultado:

+------------+
| r          |
+------------+
| china      |
+------------+

Agrupe por expressão de coluna:

SELECT 2 + total_price AS r FROM sale_detail GROUP BY 2 + total_price;

Resultado:

+------------+
| r          |
+------------+
| 102.1      |
| 102.2      |
| 102.3      |
+------------+

Colunas não agregadas no SELECT devem estar todas no GROUP BY (incorreto vs. correto):

-- Incorrect: total_price is not in GROUP BY.
SELECT region, total_price FROM sale_detail GROUP BY region;

-- Correct:
SELECT region, total_price FROM sale_detail GROUP BY region, total_price;

Resultado da instrução correta:

+------------+-------------+
| region     | total_price |
+------------+-------------+
| china      | 100.1       |
| china      | 100.2       |
| china      | 100.3       |
+------------+-------------+

Alias posicional no GROUP BY

Execute SET odps.sql.groupby.position.alias=true; (ou SET hive.groupby.position.alias=true;) antes da instrução SELECT para tratar constantes inteiras no GROUP BY como posições de coluna no SELECT:

SET odps.sql.groupby.position.alias=true;
-- 1 refers to the first column (region) in the SELECT list.
SELECT region, SUM(total_price) FROM sale_detail GROUP BY 1;

Resultado:

+------------+------------+
| region     | _c1        |
+------------+------------+
| china      | 300.6      |
+------------+------------+

Cláusula HAVING

HAVING (opcional) filtra resultados agrupados usando funções de agregação.

-- Insert additional data to demonstrate HAVING filtering.
INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai') VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);

-- Return only groups where total sales are less than 305.
SELECT region, SUM(total_price) FROM sale_detail
GROUP BY region
HAVING SUM(total_price)<305;

Resultado:

+------------+------------+
| region     | _c1        |
+------------+------------+
| china      | 300.6      |
| shanghai   | 200.9      |
+------------+------------+

ORDER BY

ORDER BY (opcional) ordena todas as linhas pela coluna ou constante especificada.

  • Ordem padrão: ascendente. Adicione DESC para descendente.

  • Por padrão, o ORDER BY deve ser seguido por LIMIT <number>. Consulte LIMIT para remover essa exigência.

  • As colunas no ORDER BY devem referenciar aliases de colunas de saída do SELECT. Se nenhum alias for especificado, o nome da coluna será usado.

  • Não é possível usar ORDER BY simultaneamente com DISTRIBUTE BY ou SORT BY.

Ordene de forma ascendente e retorne as 2 primeiras linhas:

SELECT * FROM sale_detail ORDER BY total_price LIMIT 2;

Resultado:

+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s1         | c1          | 100.1       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
+------------+-------------+-------------+------------+------------+

Ordene de forma descendente e retorne as 2 primeiras linhas:

SELECT * FROM sale_detail ORDER BY total_price DESC LIMIT 2;

Resultado:

+------------+-------------+-------------+------------+------------+
| shop_name  | customer_id | total_price | sale_date  | region     |
+------------+-------------+-------------+------------+------------+
| s3         | c3          | 100.3       | 2013       | china      |
| s2         | c2          | 100.2       | 2013       | china      |
+------------+-------------+-------------+------------+------------+

Use um alias de coluna de saída no ORDER BY:

SELECT total_price AS t FROM sale_detail ORDER BY total_price LIMIT 3;
-- Equivalent to:
SELECT total_price AS t FROM sale_detail ORDER BY t LIMIT 3;

Resultado:

+------------+
| t          |
+------------+
| 100.1      |
| 100.2      |
| 100.3      |
+------------+

Comportamento de ordenação de NULL

NULL é tratado como o menor valor no ORDER BY — o mesmo comportamento do MySQL, diferente do Oracle. Como resultado:

  • Ordem ascendente (ASC): linhas NULL aparecem primeiro.

  • Ordem descendente (DESC): linhas NULL aparecem por último.

OFFSET

Pule linhas com ORDER BY...LIMIT m OFFSET n. LIMIT m retorna m linhas; OFFSET n pula as primeiras n linhas. A forma abreviada LIMIT n, m é equivalente.

Retorne 3 linhas começando pela 3ª linha (pule as 2 primeiras):

SELECT customer_id, total_price FROM sale_detail ORDER BY total_price LIMIT 3 OFFSET 2;
-- Equivalent to:
SELECT customer_id, total_price FROM sale_detail ORDER BY total_price LIMIT 2, 3;

Resultado:

+-------------+-------------+
| customer_id | total_price |
+-------------+-------------+
| c3          | 100.3       |
+-------------+-------------+

A tabela tem apenas 3 linhas, então pular 2 retorna somente a 3ª linha.

Alias posicional no ORDER BY

Execute SET odps.sql.orderby.position.alias=true; (ou SET hive.orderby.position.alias=true;) antes da instrução SELECT para tratar constantes inteiras no ORDER BY como posições de coluna:

SET odps.sql.orderby.position.alias=true;
-- 3 refers to the third column (total_price) in the SELECT list.
SELECT * FROM sale_detail ORDER BY 3 LIMIT 3;

Resultado:

+------------+-------------+-------------+------------+------------+
| 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      |
+------------+-------------+-------------+------------+------------+

Aceleração de ordenação global

Em consultas ORDER BY padrão, todos os dados são roteados para uma única instância para ordenação, o que limita o paralelismo. O clustering por intervalo permite a ordenação global concorrente através da amostragem de dados, divisão em intervalos, ordenação paralela de cada intervalo e combinação dos resultados. Para detalhes, consulte Aceleração de ordenação global.

DISTRIBUTE BY

DISTRIBUTE BY (opcional) realiza particionamento hash nos dados com base nos valores das colunas especificadas. Ele controla como a saída do mapper é distribuída entre os reducers, garantindo que linhas com os mesmos valores de coluna vão para o mesmo reducer.

As referências de coluna no DISTRIBUTE BY devem ser aliases de colunas de saída do SELECT. Se nenhum alias for especificado, o nome da coluna será usado como alias.

Faça o particionamento hash por region:

-- All three statements below are equivalent.
SELECT region FROM sale_detail DISTRIBUTE BY region;
SELECT region AS r FROM sale_detail DISTRIBUTE BY region;
SELECT region AS r FROM sale_detail DISTRIBUTE BY r;

SORT BY

SORT BY (opcional) é tipicamente usado com DISTRIBUTE BY.

  • Ordem padrão: ascendente. Adicione DESC para descendente.

  • Não é possível usar SORT BY simultaneamente com GROUP BY.

Com DISTRIBUTE BY: Ordena linhas dentro de cada partição produzida pelo DISTRIBUTE BY.

Faça o particionamento hash por region e depois ordene por total_price ascendente dentro de cada partição:

-- Insert data for the shanghai partition.
INSERT INTO sale_detail PARTITION (sale_date='2014', region='shanghai') VALUES ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);
SELECT region, total_price FROM sale_detail DISTRIBUTE BY region SORT BY total_price;

Resultado:

+------------+-------------+
| region     | total_price |
+------------+-------------+
| shanghai   | NULL        |
| china      | 100.1       |
| china      | 100.2       |
| china      | 100.3       |
| shanghai   | 100.4       |
| shanghai   | 100.5       |
+------------+-------------+

Ordene de forma descendente dentro de cada partição:

SELECT region, total_price FROM sale_detail DISTRIBUTE BY region SORT BY total_price DESC;

Resultado:

+------------+-------------+
| region     | total_price |
+------------+-------------+
| shanghai   | 100.5       |
| shanghai   | 100.4       |
| china      | 100.3       |
| china      | 100.2       |
| china      | 100.1       |
| shanghai   | NULL        |
+------------+-------------+

Sem DISTRIBUTE BY: Ordena dados independentemente dentro de cada reducer. Isso melhora a compressão da saída e reduz a leitura de dados durante a ordenação downstream:

SELECT region, total_price FROM sale_detail SORT BY total_price DESC;

Resultado:

+------------+-------------+
| region     | total_price |
+------------+-------------+
| china      | 100.3       |
| china      | 100.2       |
| china      | 100.1       |
| shanghai   | 100.5       |
| shanghai   | 100.4       |
| shanghai   | NULL        |
+------------+-------------+

Notas de uso

  • As colunas em ORDER BY, DISTRIBUTE BY e SORT BY devem usar aliases de colunas de saída do SELECT. Os aliases de coluna podem ser caracteres chineses.

  • Como ORDER BY, DISTRIBUTE BY e SORT BY são avaliados após o SELECT, eles devem referenciar aliases de saída do SELECT.

  • Não é possível usar ORDER BY simultaneamente com DISTRIBUTE BY ou SORT BY.

  • Não é possível usar GROUP BY simultaneamente com DISTRIBUTE BY ou SORT BY.

LIMIT \<number\>

LIMIT <number> (opcional) restringe o número de linhas retornadas. O valor deve ser um inteiro de 32 bits com máximo de 2.147.483.647.

O LIMIT verifica e filtra dados no mecanismo de consulta distribuída, mas não reduz os custos de computação.

Sintaxe

LIMIT <number>
LIMIT <offset>, <count>        -- shorthand for LIMIT count OFFSET offset
LIMIT <count> OFFSET <offset>  -- skip offset rows, then return count rows

Para exemplos de OFFSET, consulte OFFSET na seção ORDER BY.

ORDER BY com LIMIT

Por padrão, o ORDER BY exige LIMIT para evitar que um único nó ordene grandes conjuntos de dados. Para remover essa exigência:

  • Nível do projeto: Execute SETPROJECT odps.sql.validate.orderby.limit=false;

  • Nível da sessão: Execute SET odps.sql.validate.orderby.limit=false; junto com a consulta

Remover esse limite pode consumir significativamente mais recursos e tempo quando um único nó tiver grandes volumes de dados para ordenar.

Máximo de linhas exibidas

Quando nenhum LIMIT é especificado, ou quando o LIMIT excede o máximo de exibição, o número de linhas mostradas é limitado:

  • Proteção de dados do projeto desativada: Controlado por instance_tunnel_max_record no arquivo config.ini do odpscmd (máximo: 10.000). Defina use_instance_tunnel=true no config.ini. Se instance_tunnel_max_record não estiver configurado, nenhum limite de linhas se aplica.

  • Proteção de dados do projeto ativada: Controlado pelo parâmetro READ_TABLE_MAX_ROW (máximo: 10.000).

Verifique se a proteção de dados do projeto está ativada:

SHOW SecurityConfiguration;

Desative a proteção de dados do projeto (padrão: desativada):

SET ProjectProtection=false;

Para mais informações, consulte Proteção de dados do projeto.

Cláusula Window

Para sintaxe e uso da cláusula window, consulte Sintaxe.