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 |
|
Executam consultas adicionais com base no resultado de uma consulta anterior |
|
|
Obtêm a interseção, união ou conjunto complementar de dois conjuntos de dados |
|
|
Unem tabelas com base em condições de junção e consulta |
|
|
Filtram dados da tabela esquerda usando a tabela direita; retornam apenas dados presentes na tabela esquerda |
|
|
Especificam dicas MAPJOIN para otimizar o desempenho de JOIN em uma tabela grande e uma ou mais tabelas pequenas |
|
|
Tratam valores de chave quente e problemas de longa cauda em operações JOIN |
|
|
Usam LATERAL VIEW com uma função de valor de tabela definida pelo usuário (UDTF) para dividir uma linha em várias linhas |
|
|
Agregam e analisam dados em múltiplas dimensões |
|
|
Iniciam um subprocesso e usam entrada/saída padrão para E/S de dados |
|
|
Modificam o tamanho da divisão para controlar o paralelismo das subtarefas |
|
|
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 tantodsquantodshh, 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 usarDISTINCTcomGROUP 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,RLIKEIN,NOT INBETWEEN...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 doSELECT. As referências de coluna noGROUP BYpodem 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 BYforem 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
DESCpara descendente.Por padrão, o
ORDER BYdeve ser seguido porLIMIT <number>. Consulte LIMIT para remover essa exigência.As colunas no
ORDER BYdevem 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 BYsimultaneamente comDISTRIBUTE BYouSORT 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
DESCpara descendente.Não é possível usar
SORT BYsimultaneamente comGROUP 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 BYeSORT BYdevem usar aliases de colunas de saída do SELECT. Os aliases de coluna podem ser caracteres chineses.Como
ORDER BY,DISTRIBUTE BYeSORT BYsão avaliados após o SELECT, eles devem referenciar aliases de saída do SELECT.Não é possível usar
ORDER BYsimultaneamente comDISTRIBUTE BYouSORT BY.Não é possível usar
GROUP BYsimultaneamente comDISTRIBUTE BYouSORT 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_recordno arquivoconfig.inido odpscmd (máximo: 10.000). Definause_instance_tunnel=truenoconfig.ini. Seinstance_tunnel_max_recordnã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.