すべてのプロダクト
Search
ドキュメントセンター

PolarDB:DISTINCTとORDER byを使用した重複排除と並べ替え

最終更新日:Dec 13, 2024

DISTINCTORDER BYは2つのOracle SQL句です。 DISTINCTはクエリ結果の重複を排除し、ORDER BYはクエリ結果を並べ替えます。 2つの句を一緒に使用する場合は、構文と実行順序に注意する必要があります。 このトピックでは、Oracle SQL文でDISTINCTおよびORDER BYを使用する方法について説明します。

構文

SELECT DISTINCT column1, column2, ...
FROM table_name
WHERE condition
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;
  • SELECT DISTINCT: 結果を複製し、一意のレコードを返します。

  • FROM: 照会するテーブルを指定します。

  • どこ: オプション。 クエリ条件。

  • ORDER BY: 結果セットをソートします。 1つ以上の列を指定し、昇順 (ASC) または降順 (DESC) を選択できます。

彼らが働く方法

SQLクエリでは、DISTINCTORDER BYの前に実行されます。 システムは一意のレコードを選択し、ソートします。

employeesという名前のテーブルの構造は次のとおりです。

CREATE TABLE employees (
    employee_id INT PRIMARY KEY , - The unique ID of an employee.
    first_name VARCHAR(50) NOT NULL, -- The first name of an employee
    last_name VARCHAR(50) NOT NULL, -- The last name of an employee.
    department VARCHAR(50), -- The department of an employee.
    salary DECIMAL (10,2) CHECK (salary > 0) -- The salary of an employee.
);

INSERT INTO employees VALUES (1, 'John', 'Doe', 'Sales', 5000);
INSERT INTO employees VALUES (2, 'Jane', 'Smith', 'Marketing', 6000);
INSERT INTO employees VALUES (3, 'John', 'Doe', 'Sales', 5000);
INSERT INTO employees VALUES (4, 'Alice', 'Johnson', 'IT', 7000);
INSERT INTO employees VALUES (5, 'Bob', 'Brown', 'Sales', 5000);
  • 一意の部門値を選択し、昇順で並べ替えます。

    SELECT DISTINCT DEPARTMENT
    FROM employees
    ORDER BY DEPARTMENT ASC;

    サンプル結果:

     department 
    ------------
     IT
     Marketing
     Sales
    (3 rows)
  • 一意の給与値を選択し、降順に並べ替えます。

    SELECT DISTINCT SALARY
    FROM employees
    ORDER BY SALARY DESC;

    サンプル結果:

     salary  
    ---------
     7000.00
     6000.00
     5000.00
    (3 rows)
  • 一意の名前の値を選択し、昇順で並べ替えます。

    SELECT DISTINCT FIRST_NAME, LAST_NAME
    FROM employees
    ORDER BY FIRST_NAME ASC, LAST_NAME ASC;

    サンプル結果:

    説明

    FIRST_NAMELAST_NAMEが同じレコードが複数ある場合でも、DISTINCTが使用されているため、一意の名前が1つだけ返されます。

     first_name | last_name 
    ------------+-----------
     Alice      | Johnson
     Bob        | Brown
     Jane       | Smith
     John       | Doe
    (4 rows)

使用上の注意

  • ORDER BYの列

    ORDER BYを使用する場合、句で指定された列がSELECTステートメントに存在する必要があります。 ORDER BYでSELECTステートメントにない列を参照すると、PolarDBはエラーを返します。

    正しくない例:

    SELECT DISTINCT FIRST_NAME
    FROM employees
    ORDER BY LAST_NAME ASC;

    次のエラーメッセージが返されます。

    ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

    Oracleの互換性のために、polar_enable_distinct_orderby_new_columnパラメーターをONに設定した後、SELECTステートメントにない列を参照できます。 この機能を使用するには、次の手順を実行します。

    1. polar_enable_distinct_orderby_new_columnパラメーターをONに設定します。

      説明

      polar_enable_distinct_orderby_new_columnパラメーターは、リビジョンバージョン2.0.14.26.0のPolarDB for PostgreSQL (Oracle互換) 2.0で最初に導入されました。 クラスターのバージョンが2.0.14.26.0より前で、この機能を使用する場合は、クラスターを2.0.14.26.0以降にアップグレードします。 マイナーバージョンを表示およびアップグレードする方法の詳細については、「バージョン管理」をご参照ください。

    2. SELECTステートメントにないORDER BYの列を参照します。

    3. FETCH FIRST X rows ONLYまたはLIMITキーワードをクエリ文の最後に追加します。

      SELECT DISTINCT FIRST_NAME
      FROM employees
      ORDER BY LAST_NAME ASC
      FETCH FIRST 2 rows ONLY;
  • エイリアスの使用

    SELECTステートメントで列のエイリアスを指定し、ORDER BYでこれらのエイリアスを使用できます。

    SELECT DISTINCT FIRST_NAME AS FN
    FROM employees
    ORDER BY FN ASC;
  • ORDER BYで参照される列の位置を使用する

    列の位置を使用してデータを並べ替えることができます。 たとえば、ORDER BY 1は、データがSELECTステートメントの最初の列でソートされることを示します。

    SELECT DISTINCT FIRST_NAME, LAST_NAME
    FROM employees
    ORDER BY 1 ASC;

高度な使用法

  • WHEREと組み合わせる

    DISTINCTORDER BYWHEREと組み合わせて、レコードをフィルタリングできます。

    例:

    SELECT DISTINCT DEPARTMENT
    FROM employees
    WHERE SALARY > 5000
    ORDER BY DEPARTMENT ASC;

    サンプル結果:

     department 
    ------------
     IT
     Marketing
    (2 rows)
  • サブクエリとの組み合わせ

    一部の複雑なクエリシナリオでは、DISTINCTORDER BYをサブクエリと組み合わせることができます。

    例:

    給与が最も高い部門を選択し、部門を並べ替えます。

    SELECT DEPARTMENT, MAX(SALARY) AS MAX_SALARY
    FROM employees
    GROUP BY DEPARTMENT
    ORDER BY DEPARTMENT ASC;

    サンプル結果:

     department | max_salary 
    ------------+------------
     IT         |    7000.00
     Marketing  |    6000.00
     Sales      |    5000.00
    (3 rows)
  • ウィンドウ関数との組み合わせ

    DISTINCTORDER BYをウィンドウ関数と組み合わせて、より複雑なデータ分析を実装できます。

    例:

    各部門で最も給与の高い従業員を選択し、給与の降順で部門を並べ替えます。

    SELECT DISTINCT DEPARTMENT, FIRST_NAME, LAST_NAME, SALARY
    FROM (
        SELECT DEPARTMENT, FIRST_NAME, LAST_NAME, SALARY,
               ROW_NUMBER() OVER (PARTITION BY DEPARTMENT ORDER BY SALARY DESC) AS rn
        FROM employees
    )
    WHERE rn = 1
    ORDER BY SALARY DESC;

    サンプル結果:

     department | first_name | last_name | salary 
    ------------+------------+-----------+--------
     IT         | Alice      | Johnson   |   7000
     Marketing  | Jane       | Smith     |   6000
     Sales      | John       | Doe       |   5000
    (3 rows)

一般的なエラーとデバッグ

WHEREで指定されていない列をソートします

ORDER BYの列に記載されているように、ORDER BYSELECTステートメントにない列を使用するとエラーが返されます。 ORDER BYで指定されたすべての列がSELECTステートメントに存在するか、エイリアスまたは列位置を使用する必要があります。

説明

polar_enable_distinct_orderby_new_columnパラメーターをONに設定し、FETCH FIRST X rows ONLYキーワードを追加すると、DISTINCTORDER BYの列を暗黙的に参照できるようになります。

DISTINCTの報道を混乱させる

DISTINCTは、単一の列だけでなく、SELECTステートメントのすべての列に適用されます。 したがって、複数の列を指定するSELECT DISTINCTステートメントは、指定したすべての列の重複を排除します。

例:

SELECT DISTINCT FIRST_NAME, DEPARTMENT
FROM employees
ORDER BY FIRST_NAME ASC;

上記のSQLステートメントは、FIRST_NAMEだけでなく、FIRST_NAMEDEPARTMENTを使用してフィルタリングされたレコードの重複排除を行います。

パフォーマンスの改善

大きなデータセットが含まれる場合、DISTINCTORDER BYを使用すると、クエリのパフォーマンスに影響があります。 次の最適化の提案を使用できます。

  • インデックスの最適化: WHEREDISTINCT、およびORDER BYで指定された列に適切なインデックスを作成し、クエリを高速化します。

  • 返される列の最小化: 処理するデータ量を減らすために必要な列のみを選択します。

  • 分割を使用する: 大きなテーブルを分割して、クエリ効率を向上させることができます。

  • 実行計画の分析: EXPLAIN planステートメントを使用して、実行計画を分析し、潜在的なパフォーマンスのボトルネックを特定します。

例:

インデックス最適化を使用します。

-- Create an index to optimize queries on the DEPARTMENT column.
CREATE INDEX idx_employees_department ON employees(DEPARTMENT);

概要

DISTINCTORDER BYは、レコードの重複排除と結果セットの並べ替えのためのPolarDBの強力なSQLツールです。 それらの仕組み、構文、一般的なシナリオを理解することで、クエリの効率と精度を向上させることができます。 これらの2つの句を他のSQL機能と組み合わせて、複雑なデータ処理および分析タスクを実装できます。