このトピックでは、MaxCompute SQL文の一般的な使用シナリオとその記述方法について説明します。
データセットの準備
この例では、empテーブルとdeptテーブルがデータセットとして使用されます。 MaxComputeプロジェクトでテーブルを作成し、テーブルにデータをアップロードするには、次の手順を実行します。
テーブルを作成します。
次のステートメントを実行して、empテーブルを作成します。
CREATE TABLE IF NOT EXISTS emp ( EMPNO STRING, ENAME STRING, JOB STRING, MGR BIGINT, HIREDATE DATETIME, SAL DOUBLE, COMM DOUBLE, DEPTNO BIGINT);次のステートメントを実行して、deptテーブルを作成します。
CREATE TABLE IF NOT EXISTS dept ( DEPTNO BIGINT, DNAME STRING, LOC STRING);
次の内容で、ファイル
emp.txtとdept.txtをローカルに作成します。emp.txt
7369,SMITH,CLERK,7902,1980-12-17 00:00:00,800,,20 7499,ALLEN,SALESMAN,7698,1981-02-20 00:00:00,1600,300,30 7521,WARD,SALESMAN,7698,1981-02-22 00:00:00,1250,500,30 7566,JONES,MANAGER,7839,1981-04-02 00:00:00,2975,,20 7654,MARTIN,SALESMAN,7698,1981-09-28 00:00:00,1250,1400,30 7698,BLAKE,MANAGER,7839,1981-05-01 00:00:00,2850,,30 7782,CLARK,MANAGER,7839,1981-06-09 00:00:00,2450,,10 7788,SCOTT,ANALYST,7566,1987-04-19 00:00:00,3000,,20 7839,KING,PRESIDENT,,1981-11-17 00:00:00,5000,,10 7844,TURNER,SALESMAN,7698,1981-09-08 00:00:00,1500,0,30 7876,ADAMS,CLERK,7788,1987-05-23 00:00:00,1100,,20 7900,JAMES,CLERK,7698,1981-12-03 00:00:00,950,,30 7902,FORD,ANALYST,7566,1981-12-03 00:00:00,3000,,20 7934,MILLER,CLERK,7782,1982-01-23 00:00:00,1300,,10dept.txt
10,ACCOUNTING,NEW YORK 20,RESEARCH,DALLAS 30,SALES,CHICAGO 40,OPERATIONS,BOSTONテーブルにデータをアップロードします。 詳細については、「データアップロードシナリオとツール」をご参照ください。
例
例1: 少なくとも1人の従業員がいるすべての部門を照会します。
クエリ内の大量のデータを避けるために、JOIN句を使用することをお勧めします。 次のSQL文を実行します。
SELECT d.* FROM dept d JOIN ( SELECT DISTINCT deptno AS no FROM emp ) e ON d.deptno = e.no;次の応答が返されます。
+------------+------------+------------+ | deptno | dname | loc | +------------+------------+------------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | +------------+------------+------------+例2: SMITHより高い給与を持つすべての従業員を照会します。
次のサンプルコードは、SQL文でMAPJOINを使用する方法を示しています。
SELECT /*+ MapJoin(a) */ e.empno , e.ename , e.sal FROM emp e JOIN ( SELECT MAX(sal) AS sal FROM `emp` WHERE `ENAME` = 'SMITH' ) a ON e.sal > a.sal;次の応答が返されます。
+------------+------------+------------+ | empno | ename | sal | +------------+------------+------------+ | 7499 | ALLEN | 1600.0 | | 7521 | WARD | 1250.0 | | 7566 | JONES | 2975.0 | | 7654 | MARTIN | 1250.0 | | 7698 | BLAKE | 2850.0 | | 7782 | CLARK | 2450.0 | | 7788 | SCOTT | 3000.0 | | 7839 | KING | 5000.0 | | 7844 | TURNER | 1500.0 | | 7876 | ADAMS | 1100.0 | | 7900 | JAMES | 950.0 | | 7902 | FORD | 3000.0 | | 7934 | MILLER | 1300.0 | +------------+------------+------------+例3: すべての従業員の名前と上司の名前を照会します。
次のサンプルコードは、SQL文でEQUI JOINを使用する方法を示しています。
SELECT a.ename , b.ename FROM emp a LEFT OUTER JOIN emp b ON b.empno = a.mgr;次の応答が返されます。
+------------+------------+ | ename | ename2 | +------------+------------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +------------+------------+例4: 基本給与がUSD 1,500より高いすべてのジョブを照会します。
次のサンプルコードは、SQL文でHAVING句を使用する方法を示しています。
SELECT emp.`JOB` , MIN(emp.sal) AS sal FROM `emp` GROUP BY emp.`JOB` HAVING MIN(emp.sal) > 1500;次の応答が返されます。
+------------+------------+ | job | sal | +------------+------------+ | MANAGER | 2450.0 | | ANALYST | 3000.0 | | PRESIDENT | 5000.0 | +------------+------------+例5: 各部門の従業員数、平均給与、および平均勤続年数を照会します。
次のサンプルコードは、SQL文で組み込み関数を使用する方法を示しています。
SELECT COUNT(empno) AS cnt_emp , ROUND(AVG(sal), 2) AS avg_sal , ROUND(AVG(datediff(getdate(), hiredate, 'dd')), 2) AS avg_hire FROM `emp` GROUP BY `DEPTNO`;次の応答が返されます。
+------------+------------+------------+ | cnt_emp | avg_sal | avg_hire | +------------+------------+------------+ | 5 | 2175.0 | 14886.2 | | 6 | 1566.67 | 15715.33 | | 3 | 2916.67 | 15606.33 | +------------+------------+------------+例6: 各部門の給与が最も高い上位3人の従業員の名前とランクを照会します。
次のサンプルコードは、上位N件の結果を照会する方法を示しています。
SELECT * FROM ( SELECT deptno , ename , sal , ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal DESC) AS nums FROM emp ) emp1 WHERE emp1.nums < 4;次の応答が返されます。
+------------+------------+------------+------------+ | deptno | ename | sal | nums | +------------+------------+------------+------------+ | 10 | KING | 5000.0 | 1 | | 10 | CLARK | 2450.0 | 2 | | 10 | MILLER | 1300.0 | 3 | | 20 | SCOTT | 3000.0 | 1 | | 20 | FORD | 3000.0 | 2 | | 20 | JONES | 2975.0 | 3 | | 30 | BLAKE | 2850.0 | 1 | | 30 | ALLEN | 1600.0 | 2 | | 30 | TURNER | 1500.0 | 3 | +------------+------------+------------+------------+例7: 各部門の従業員数と各部門の店員の割合を照会します。
SELECT deptno , COUNT(empno) AS cnt , ROUND(SUM(CASE WHEN job = 'CLERK' THEN 1 ELSE 0 END) / COUNT(empno), 2) AS rate FROM `EMP` GROUP BY deptno;次の応答が返されます。
+------------+------------+------------+ | deptno | cnt | rate | +------------+------------+------------+ | 20 | 5 | 0.4 | | 30 | 6 | 0.17 | | 10 | 3 | 0.33 | +------------+------------+------------+
注意事項
GROUP BY句を使用する場合、SELECTリストはGROUP BY句の集計関数と列のみで構成できます。
ORDER BYの後にLIMIT Nが続く必要があります。
SELECT式はサブクエリをサポートしていません。 サブクエリを使用するには、JOIN句を含めるようにコードを書き換えます。
JOIN句はデカルト積をサポートしていません。 代わりにMAPJOINを使用できます。
UNION ALLはサブクエリで使用する必要があります。
in句またはNOT IN句で指定されたサブクエリには、1つの列のみを含めることができ、最大1,000行を返すことができます。 それ以外の場合は、JOIN句を使用します。