<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_ORDER_BY</id>
	<title>MySQL - ORDER BY - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_ORDER_BY"/>
	<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=MySQL_-_ORDER_BY&amp;action=history"/>
	<updated>2026-06-13T21:03:02Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://mochiu.net/index.php?title=MySQL_-_ORDER_BY&amp;diff=14266&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == &lt;code&gt;ORDER BY&lt;/code&gt; 句は、クエリ結果の並び順を指定するために使用される。&lt;br&gt; &lt;br&gt; &lt;code&gt;SELECT&lt;/code&gt; 文の末尾に記述し、指定した列の値に基づいて結果セットをソートする。&lt;br&gt; 昇順 (ASC) または降順 (DESC) を指定でき、複数列による多段階ソートも可能である。&lt;br&gt; &lt;br&gt; &lt;code&gt;ORDER BY&lt;/code&gt; 句は、単純な列名の指定だけでなく、関数の結果、式、CASE…」</title>
		<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=MySQL_-_ORDER_BY&amp;diff=14266&amp;oldid=prev"/>
		<updated>2026-02-08T03:35:55Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句は、クエリ結果の並び順を指定するために使用される。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; 文の末尾に記述し、指定した列の値に基づいて結果セットをソートする。&amp;lt;br&amp;gt; 昇順 (ASC) または降順 (DESC) を指定でき、複数列による多段階ソートも可能である。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句は、単純な列名の指定だけでなく、関数の結果、式、CASE…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
&amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句は、クエリ結果の並び順を指定するために使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; 文の末尾に記述し、指定した列の値に基づいて結果セットをソートする。&amp;lt;br&amp;gt;&lt;br /&gt;
昇順 (ASC) または降順 (DESC) を指定でき、複数列による多段階ソートも可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句は、単純な列名の指定だけでなく、関数の結果、式、CASE式、列番号、エイリアス等、柔軟な指定方法をサポートしている。&amp;lt;br&amp;gt;&lt;br /&gt;
また、&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; 句と組み合わせることにより、上位N件の取得やページネーションの実装が可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
パフォーマンスの観点では、インデックスの有無が実行速度に大きく影響する。&amp;lt;br&amp;gt;&lt;br /&gt;
インデックスを使用できる場合、MySQLはファイルソート (&amp;lt;code&amp;gt;filesort&amp;lt;/code&amp;gt;) を回避し、インデックス順で直接データを読み取ることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
インデックスを使用できない場合は、ソートバッファを使用した &amp;lt;code&amp;gt;filesort&amp;lt;/code&amp;gt; が発生し、大量のデータに対してはディスクソートが必要になる場合がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0以降では、ウィンドウ関数と組み合わせた高度なソート処理や、インクリメンタルソートバッファ割り当て等の最適化が導入されている。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 基本構文 ==&lt;br /&gt;
==== ORDER BY句の基本形式 ====&lt;br /&gt;
ORDER BY句は、SELECT文の末尾に記述する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 基本構文&lt;br /&gt;
 SELECT column1, column2, ...&lt;br /&gt;
    FROM table_name&lt;br /&gt;
    ORDER BY column [ASC|DESC];&lt;br /&gt;
 &lt;br /&gt;
 # 昇順ソート (ASC、デフォルト)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary ASC;&lt;br /&gt;
 &lt;br /&gt;
 # 降順ソート (DESC)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 &lt;br /&gt;
 # ASCは省略可能&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ASC&amp;lt;/code&amp;gt; は昇順 (Ascending) を意味し、小さい値から大きい値の順にソートされる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;DESC&amp;lt;/code&amp;gt; は降順 (Descending) を意味し、大きい値から小さい値の順にソートされる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ASC&amp;lt;/code&amp;gt; を指定しない場合、デフォルトで昇順ソートとなる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複数列によるソート ====&lt;br /&gt;
複数の列を指定することで、多段階のソートが可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 複数列によるソート&lt;br /&gt;
 SELECT name, department_id, salary FROM employees&lt;br /&gt;
    ORDER BY department_id ASC, salary DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 最初の列で並び替え、同値の場合は2番目の列で並び替え&lt;br /&gt;
 SELECT product_name, category_id, price FROM products&lt;br /&gt;
    ORDER BY category_id, price DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 3つ以上の列でソート&lt;br /&gt;
 SELECT name, department_id, hire_date, salary FROM employees&lt;br /&gt;
    ORDER BY department_id, hire_date DESC, salary DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
複数列を指定した場合、最初の列でソートし、同値の行については2番目の列でソート、さらに同値の場合は3番目の列でソート、という処理が行われる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
各列ごとに &amp;lt;code&amp;gt;ASC&amp;lt;/code&amp;gt; または &amp;lt;code&amp;gt;DESC&amp;lt;/code&amp;gt; を個別に指定できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 各列ごとにソート順を指定&lt;br /&gt;
 SELECT name, department_id, salary FROM employees&lt;br /&gt;
    ORDER BY department_id ASC, salary DESC;&lt;br /&gt;
 # department_idは昇順、salaryは降順&lt;br /&gt;
 &lt;br /&gt;
 # 混在も可能&lt;br /&gt;
 SELECT name, hire_date, salary FROM employees&lt;br /&gt;
    ORDER BY hire_date DESC, salary ASC;&lt;br /&gt;
 # hire_dateは降順、salaryは昇順&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 列番号とエイリアスによるソート ==&lt;br /&gt;
==== 列番号によるソート ====&lt;br /&gt;
ORDER BY句では、SELECT句に記述した列の順序を示す番号 (1から始まる) を指定できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 列番号によるソート&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY 2 DESC;&lt;br /&gt;
 # 2番目の列 (salary) で降順ソート&lt;br /&gt;
 &lt;br /&gt;
 # 複数列の指定も可能&lt;br /&gt;
 SELECT name, department_id, salary FROM employees&lt;br /&gt;
    ORDER BY 2 ASC, 3 DESC;&lt;br /&gt;
 # 2番目の列 (department_id) で昇順、3番目の列 (salary) で降順&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ただし、列番号によるソートは非推奨である。&amp;lt;br&amp;gt;&lt;br /&gt;
理由は、SELECT句の列順序が変更されると、ソート対象も意図せず変わってしまうためである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 列番号は非推奨&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY 1 DESC;&lt;br /&gt;
 # nameで降順ソート&lt;br /&gt;
 &lt;br /&gt;
 # SELECT句が変更されると、ソート対象も変わる&lt;br /&gt;
 SELECT salary, name FROM employees&lt;br /&gt;
    ORDER BY 1 DESC;&lt;br /&gt;
 # salaryで降順ソート (意図と異なる可能性)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
列名を直接指定する方が、保守性と可読性が高い。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== エイリアスによるソート ====&lt;br /&gt;
SELECT句で定義した列のエイリアス (別名) をORDER BY句で使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # エイリアスによるソート&lt;br /&gt;
 SELECT name, salary * 12 AS annual_salary FROM employees&lt;br /&gt;
    ORDER BY annual_salary DESC;&lt;br /&gt;
 &lt;br /&gt;
 # CONCAT関数の結果にエイリアスを付けてソート&lt;br /&gt;
 SELECT CONCAT(first_name, &amp;#039; &amp;#039;, last_name) AS full_name FROM employees&lt;br /&gt;
    ORDER BY full_name;&lt;br /&gt;
 &lt;br /&gt;
 # 複数のエイリアスを使用&lt;br /&gt;
 SELECT&lt;br /&gt;
    name,&lt;br /&gt;
    salary * 12 AS annual_salary,&lt;br /&gt;
    YEAR(hire_date) AS hire_year&lt;br /&gt;
    FROM employees&lt;br /&gt;
    ORDER BY hire_year DESC, annual_salary DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
エイリアスにバッククォート (`) を使用すると、予約語や特殊文字を含む名前も使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # バッククォートを使用したエイリアス&lt;br /&gt;
 SELECT salary * 12 AS `年収` FROM employees&lt;br /&gt;
    ORDER BY `年収` DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 予約語をエイリアスとして使用&lt;br /&gt;
 SELECT name AS `order` FROM employees&lt;br /&gt;
    ORDER BY `order`;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
エイリアスを使用することで、複雑な式をORDER BY句で再記述する必要がなくなり、可読性が向上する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== NULLの扱い ==&lt;br /&gt;
==== NULLの基本的な動作 ====&lt;br /&gt;
ORDER BY句では、&amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; 値は最小値として扱われる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # NULLは最小値扱い&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary ASC;&lt;br /&gt;
 # NULLが最初、次に小さい値から大きい値の順&lt;br /&gt;
 &lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 # 大きい値から小さい値の順、最後にNULL&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ASC&amp;lt;/code&amp;gt; (昇順) では、&amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; が最初に表示される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;DESC&amp;lt;/code&amp;gt; (降順) では、&amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; が最後に表示される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== NULLを最後に配置する方法 ====&lt;br /&gt;
NULLを最後に配置したい場合、&amp;lt;code&amp;gt;ISNULL()&amp;lt;/code&amp;gt; 関数または &amp;lt;code&amp;gt;IS NULL&amp;lt;/code&amp;gt; を使用する方法がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # ISNULL()関数を使用してNULLを最後に配置&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY ISNULL(salary) ASC, salary ASC;&lt;br /&gt;
 # ISNULL(salary)は、NULLの場合1、それ以外は0を返す&lt;br /&gt;
 # 0 (非NULL) が最初、1 (NULL) が最後になる&lt;br /&gt;
 &lt;br /&gt;
 # IS NULLを使用した方法&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary IS NULL, salary ASC;&lt;br /&gt;
 # salary IS NULLは、NULLの場合1、それ以外は0を返す&lt;br /&gt;
 &lt;br /&gt;
 # 降順でNULLを最後に配置&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY ISNULL(salary) ASC, salary DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ISNULL(column)&amp;lt;/code&amp;gt; は、NULLの場合に &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;、それ以外の場合に &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
この特性を利用して、非NULL値を先にソートし、NULLを最後に配置できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== COALESCE()関数による代替値指定 ====&lt;br /&gt;
&amp;lt;code&amp;gt;COALESCE()&amp;lt;/code&amp;gt; 関数を使用すると、&amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; に代替値を指定してソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # COALESCE()で代替値を指定&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY COALESCE(salary, 9999999) ASC;&lt;br /&gt;
 # salaryがNULLの場合、9999999として扱われる&lt;br /&gt;
 &lt;br /&gt;
 # NULLを最小値として扱う&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY COALESCE(salary, 0) DESC;&lt;br /&gt;
 # salaryがNULLの場合、0として扱われる&lt;br /&gt;
 &lt;br /&gt;
 # 文字列の場合&lt;br /&gt;
 SELECT name, department_name FROM employees&lt;br /&gt;
    ORDER BY COALESCE(department_name, &amp;#039;ZZZZZ&amp;#039;);&lt;br /&gt;
 # department_nameがNULLの場合、&amp;#039;ZZZZZ&amp;#039;として扱われ、最後に配置される&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;COALESCE(column, default_value)&amp;lt;/code&amp;gt; は、&amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt; がNULLの場合に &amp;lt;code&amp;gt;default_value&amp;lt;/code&amp;gt; を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、NULLを任意の値として扱ってソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 式と関数によるソート ==&lt;br /&gt;
==== 関数の結果によるソート ====&lt;br /&gt;
ORDER BY句では、列名だけでなく、関数の結果でソートすることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # LENGTH()関数で文字列の長さでソート&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
    ORDER BY LENGTH(name) DESC;&lt;br /&gt;
 &lt;br /&gt;
 # YEAR()関数で年だけを抽出してソート&lt;br /&gt;
 SELECT name, hire_date FROM employees&lt;br /&gt;
    ORDER BY YEAR(hire_date) DESC;&lt;br /&gt;
 &lt;br /&gt;
 # MONTH()関数で月だけを抽出してソート&lt;br /&gt;
 SELECT name, hire_date FROM employees&lt;br /&gt;
    ORDER BY MONTH(hire_date), DAY(hire_date);&lt;br /&gt;
 &lt;br /&gt;
 # UPPER()関数で大文字小文字を無視してソート&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
    ORDER BY UPPER(name);&lt;br /&gt;
 &lt;br /&gt;
 # ABS()関数で絶対値でソート&lt;br /&gt;
 SELECT name, balance FROM accounts&lt;br /&gt;
    ORDER BY ABS(balance) DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
関数を使用することで、データの加工結果に基づいたソートが可能になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 式によるソート ====&lt;br /&gt;
ORDER BY句では、算術演算やその他の式を使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 算術演算の結果でソート&lt;br /&gt;
 SELECT name, salary, bonus FROM employees&lt;br /&gt;
    ORDER BY salary + bonus DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 複数列の演算結果でソート&lt;br /&gt;
 SELECT product_name, price, quantity FROM products&lt;br /&gt;
    ORDER BY price * quantity DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 条件式と組み合わせたソート&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary / 12 DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
式によるソートは、計算結果に基づいた柔軟なソートを実現する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== CASE式によるカスタムソート ====&lt;br /&gt;
&amp;lt;code&amp;gt;CASE&amp;lt;/code&amp;gt; 式を使用すると、カスタムの優先順位でソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # CASE式でステータスの優先順位を指定&lt;br /&gt;
 SELECT order_id, status FROM orders&lt;br /&gt;
    ORDER BY&lt;br /&gt;
       CASE status&lt;br /&gt;
          WHEN &amp;#039;urgent&amp;#039; THEN 1&lt;br /&gt;
          WHEN &amp;#039;processing&amp;#039; THEN 2&lt;br /&gt;
          WHEN &amp;#039;pending&amp;#039; THEN 3&lt;br /&gt;
          WHEN &amp;#039;completed&amp;#039; THEN 4&lt;br /&gt;
          ELSE 5&lt;br /&gt;
       END;&lt;br /&gt;
 &lt;br /&gt;
 # 複数条件での優先順位指定&lt;br /&gt;
 SELECT name, department_id, salary FROM employees&lt;br /&gt;
    ORDER BY&lt;br /&gt;
       CASE&lt;br /&gt;
          WHEN department_id = 10 THEN 1&lt;br /&gt;
          WHEN department_id = 20 THEN 2&lt;br /&gt;
          ELSE 3&lt;br /&gt;
       END,&lt;br /&gt;
       salary DESC;&lt;br /&gt;
 &lt;br /&gt;
 # NULL値を特定の位置に配置&lt;br /&gt;
 SELECT name, manager_id FROM employees&lt;br /&gt;
    ORDER BY&lt;br /&gt;
       CASE&lt;br /&gt;
          WHEN manager_id IS NULL THEN 0&lt;br /&gt;
          ELSE 1&lt;br /&gt;
       END,&lt;br /&gt;
       manager_id;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;CASE&amp;lt;/code&amp;gt; 式を使用することで、ビジネスロジックに基づいた任意の順序でソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== FIELD()関数による任意順序指定 ====&lt;br /&gt;
&amp;lt;code&amp;gt;FIELD()&amp;lt;/code&amp;gt; 関数を使用すると、任意の順序でソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # FIELD()関数で任意順序を指定&lt;br /&gt;
 SELECT name, status FROM orders&lt;br /&gt;
    ORDER BY FIELD(status, &amp;#039;urgent&amp;#039;, &amp;#039;processing&amp;#039;, &amp;#039;pending&amp;#039;, &amp;#039;completed&amp;#039;);&lt;br /&gt;
 &lt;br /&gt;
 # 特定の値を優先的にソート&lt;br /&gt;
 SELECT product_name, category FROM products&lt;br /&gt;
    ORDER BY FIELD(category, &amp;#039;Electronics&amp;#039;, &amp;#039;Books&amp;#039;, &amp;#039;Clothing&amp;#039;), price;&lt;br /&gt;
 &lt;br /&gt;
 # 任意の値リストでソート&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
    ORDER BY FIELD(department_id, 30, 10, 20);&lt;br /&gt;
 # department_idが30、10、20の順で表示される&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;FIELD(column, value1, value2, value3, ...)&amp;lt;/code&amp;gt; は、&amp;lt;code&amp;gt;column&amp;lt;/code&amp;gt; が &amp;lt;code&amp;gt;value1&amp;lt;/code&amp;gt; の場合に1、&amp;lt;code&amp;gt;value2&amp;lt;/code&amp;gt; の場合に2、という順序番号を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、任意の順序でソートできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LIMITとの組み合わせ ==&lt;br /&gt;
==== 上位N件の取得 ====&lt;br /&gt;
ORDER BY句とLIMIT句を組み合わせることにより、ソート後の上位N件を取得できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 上位10件の給与を取得&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 &lt;br /&gt;
 # 最新の5件の注文を取得&lt;br /&gt;
 SELECT order_id, ordered_at FROM orders&lt;br /&gt;
    ORDER BY ordered_at DESC&lt;br /&gt;
    LIMIT 5;&lt;br /&gt;
 &lt;br /&gt;
 # 価格が最も高い商品を取得&lt;br /&gt;
 SELECT product_name, price FROM products&lt;br /&gt;
    ORDER BY price DESC&lt;br /&gt;
    LIMIT 1;&lt;br /&gt;
 &lt;br /&gt;
 # 最も古い3件のレコードを取得&lt;br /&gt;
 SELECT name, hire_date FROM employees&lt;br /&gt;
    ORDER BY hire_date ASC&lt;br /&gt;
    LIMIT 3;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; 句は、ソート後の結果から指定した件数のみを返す。&amp;lt;br&amp;gt;&lt;br /&gt;
詳細は、[[MySQL - LIMIT句]]のページを参照すること。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== ページネーション ====&lt;br /&gt;
&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; 句と &amp;lt;code&amp;gt;OFFSET&amp;lt;/code&amp;gt; を組み合わせることにより、ページネーション (ページ分割) を実装できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 最初の10件 (ページ1)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10 OFFSET 0;&lt;br /&gt;
 &lt;br /&gt;
 # 11件目から20件目 (ページ2)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10 OFFSET 10;&lt;br /&gt;
 &lt;br /&gt;
 # 21件目から30件目 (ページ3)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10 OFFSET 20;&lt;br /&gt;
 &lt;br /&gt;
 # 一般的な形式&lt;br /&gt;
 # LIMIT rows OFFSET (page - 1) * rows&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ただし、&amp;lt;code&amp;gt;OFFSET&amp;lt;/code&amp;gt; を使用したページネーションは、大きなオフセット値に対してパフォーマンスが低下する。&amp;lt;br&amp;gt;&lt;br /&gt;
MySQLは、オフセット分の行を読み飛ばす必要があるためである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== シーク法 (キーセットページネーション) ====&lt;br /&gt;
大量のデータに対するページネーションでは、シーク法 (キーセットページネーション) が推奨される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 最初のページ (通常通り)&lt;br /&gt;
 SELECT id, name, created_at FROM posts&lt;br /&gt;
    ORDER BY id DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 # 結果: id = 100, 99, 98, ..., 91 (最後のidは91)&lt;br /&gt;
 &lt;br /&gt;
 # 次のページ (WHERE句で前ページの最後のidより小さいものを取得)&lt;br /&gt;
 SELECT id, name, created_at FROM posts&lt;br /&gt;
    WHERE id &amp;lt; 91&lt;br /&gt;
    ORDER BY id DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 # 結果: id = 90, 89, 88, ..., 81&lt;br /&gt;
 &lt;br /&gt;
 # さらに次のページ&lt;br /&gt;
 SELECT id, name, created_at FROM posts&lt;br /&gt;
    WHERE id &amp;lt; 81&lt;br /&gt;
    ORDER BY id DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
シーク法は、インデックスを効率的に使用できるため、大量のデータに対しても高速である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 昇順ソートの場合&lt;br /&gt;
 SELECT id, name FROM employees&lt;br /&gt;
    WHERE id &amp;gt; 100&lt;br /&gt;
    ORDER BY id ASC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 &lt;br /&gt;
 # 複合ソートの場合&lt;br /&gt;
 SELECT id, name, created_at FROM posts&lt;br /&gt;
    WHERE (created_at, id) &amp;lt; (&amp;#039;2024-01-01&amp;#039;, 100)&lt;br /&gt;
    ORDER BY created_at DESC, id DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== パフォーマンス最適化 ==&lt;br /&gt;
==== インデックスによるORDER BY最適化 ====&lt;br /&gt;
ORDER BY句で指定した列にインデックスが存在する場合、MySQLはインデックス順でデータを読み取ることができる。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、ファイルソート (&amp;lt;code&amp;gt;filesort&amp;lt;/code&amp;gt;) を回避し、高速にソートを実行できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # インデックスが使用される例&lt;br /&gt;
 CREATE INDEX idx_salary ON employees(salary);&lt;br /&gt;
 &lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 # インデックスが使用され、filesortは発生しない&lt;br /&gt;
 &lt;br /&gt;
 # WHERE句とORDER BY句の列が同一インデックスに含まれる場合&lt;br /&gt;
 CREATE INDEX idx_dept_salary ON employees(department_id, salary);&lt;br /&gt;
 &lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    WHERE department_id = 10&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 # インデックスが使用され、filesortは発生しない&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
インデックスを使用できる条件は以下の通りである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句の列にインデックスが存在する&lt;br /&gt;
*: 単一列または複合インデックスの先頭列から順に使用されている。&lt;br /&gt;
* &amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt; 句と &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句の列が同一インデックスに含まれる&lt;br /&gt;
*: &amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt; 句の列とソート列が同一のインデックスに含まれている場合、インデックスのみで処理できる。&lt;br /&gt;
* ソート順がインデックスの順序と一致する&lt;br /&gt;
*: インデックスは昇順で作成されるため、昇順ソートが最も効率的。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== filesort (ファイルソート) ====&lt;br /&gt;
インデックスを使用できない場合、MySQLはファイルソート (&amp;lt;code&amp;gt;filesort&amp;lt;/code&amp;gt;) を実行する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # filesortが発生する例&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 # salaryにインデックスがない場合、filesortが発生&lt;br /&gt;
 &lt;br /&gt;
 # 複数列のソートでインデックスが使用できない場合&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY department_id, hire_date DESC;&lt;br /&gt;
 # (department_id, hire_date)のインデックスがない場合、filesortが発生&lt;br /&gt;
 &lt;br /&gt;
 # 関数を使用したソート&lt;br /&gt;
 SELECT name, hire_date FROM employees&lt;br /&gt;
    ORDER BY YEAR(hire_date);&lt;br /&gt;
 # 関数を使用しているため、インデックスが使用できず、filesortが発生&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ファイルソートには、以下に示す3つのアルゴリズムがある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;sort_key, rowid&amp;gt;&amp;lt;/code&amp;gt; アルゴリズム&lt;br /&gt;
*: ソートキーと行IDをソートし、ソート後に再度テーブルを読み取る。&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;sort_key, additional_fields&amp;gt;&amp;lt;/code&amp;gt; アルゴリズム&lt;br /&gt;
*: ソートキーと必要な列を全てソートバッファに格納し、再読み取りを回避する。&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;sort_key, packed_additional_fields&amp;gt;&amp;lt;/code&amp;gt; アルゴリズム&lt;br /&gt;
*: ソートキーと必要な列を圧縮形式で格納する。最も効率的。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQLは、データの特性とソートバッファのサイズに基づいて、最適なアルゴリズムを自動的に選択する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== sort_buffer_sizeの調整 ====&lt;br /&gt;
&amp;lt;code&amp;gt;sort_buffer_size&amp;lt;/code&amp;gt; は、ファイルソート用のメモリバッファサイズを指定する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # 現在の設定を確認&lt;br /&gt;
 SHOW VARIABLES LIKE &amp;#039;sort_buffer_size&amp;#039;;&lt;br /&gt;
 # デフォルト: 256[KB] (262144バイト)&lt;br /&gt;
 &lt;br /&gt;
 # セッション単位で変更&lt;br /&gt;
 SET SESSION sort_buffer_size = 1048576;&lt;br /&gt;
 # 1[MB]に変更&lt;br /&gt;
 &lt;br /&gt;
 # グローバルで変更&lt;br /&gt;
 SET GLOBAL sort_buffer_size = 2097152;&lt;br /&gt;
 # 2[MB]に変更&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;code&amp;gt;sort_buffer_size&amp;lt;/code&amp;gt; を増やすと、大量のデータをメモリ内でソートできるため、ディスクI/Oを削減できる。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;ただし、各セッションごとにバッファが確保されるため、過度に大きくするとメモリ不足になる可能性がある。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0.12以降では、ソートバッファは増分割り当て (incremental allocation) されるため、実際に必要なメモリのみが使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== EXPLAINでの確認 ====&lt;br /&gt;
&amp;lt;code&amp;gt;EXPLAIN&amp;lt;/code&amp;gt; を使用して、ORDER BYがインデックスを使用しているか、filesortが発生しているかを確認できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # EXPLAINで実行計画を確認&lt;br /&gt;
 EXPLAIN SELECT name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 &lt;br /&gt;
 # Extra列に &amp;quot;Using filesort&amp;quot; が表示される場合、filesortが発生している&lt;br /&gt;
 # Extra列に何も表示されない場合、インデックスが使用されている&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Extra&amp;lt;/code&amp;gt; 列の内容を確認することで、ソート処理の詳細がわかる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Using filesort&amp;lt;/code&amp;gt;&lt;br /&gt;
*: ファイルソートが発生している。インデックスを使用していない。&lt;br /&gt;
* &amp;lt;code&amp;gt;Using index&amp;lt;/code&amp;gt;&lt;br /&gt;
*: インデックスのみで処理が完了している (カバリングインデックス)。&lt;br /&gt;
* &amp;lt;code&amp;gt;Using temporary; Using filesort&amp;lt;/code&amp;gt;&lt;br /&gt;
*: 一時テーブルを作成してからファイルソートを実行している。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 最適化のベストプラクティス ====&lt;br /&gt;
ORDER BY句のパフォーマンスを最適化するためのベストプラクティスを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* ソート列にインデックスを作成する&lt;br /&gt;
*: 頻繁にソートされる列にはインデックスを作成すべきである。&lt;br /&gt;
* 複合インデックスの順序に注意する&lt;br /&gt;
*: &amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt; 句とソート列を含む複合インデックスは、&amp;lt;code&amp;gt;(filter_column, sort_column)&amp;lt;/code&amp;gt; の順序で作成する。&lt;br /&gt;
* &amp;lt;code&amp;gt;SELECT *&amp;lt;/code&amp;gt; を避ける&lt;br /&gt;
*: 必要な列のみを取得することで、ソートバッファの使用量を削減できる。&lt;br /&gt;
* &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; 句を使用する&lt;br /&gt;
*: 上位N件のみが必要な場合、&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; 句を使用することで、優先キューソートが使用され、全件ソートを回避できる。&lt;br /&gt;
* 大量のデータに対するページネーションではシーク法を使用する&lt;br /&gt;
*: &amp;lt;code&amp;gt;OFFSET&amp;lt;/code&amp;gt; を避け、&amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt; 句とインデックスを活用したシーク法を使用する。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 良い例: 必要な列のみを取得&lt;br /&gt;
 SELECT id, name, salary FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 &lt;br /&gt;
 # 悪い例: SELECT *を使用&lt;br /&gt;
 SELECT * FROM employees&lt;br /&gt;
    ORDER BY salary DESC&lt;br /&gt;
    LIMIT 10;&lt;br /&gt;
 # ソートバッファに不要な列も格納される&lt;br /&gt;
 &lt;br /&gt;
 # 複合インデックスの作成例&lt;br /&gt;
 CREATE INDEX idx_dept_salary ON employees(department_id, salary);&lt;br /&gt;
 &lt;br /&gt;
 # インデックスが効率的に使用される&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
    WHERE department_id = 10&lt;br /&gt;
    ORDER BY salary DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MySQL 8.0以降の機能 ==&lt;br /&gt;
==== ウィンドウ関数でのORDER BY ====&lt;br /&gt;
MySQL 8.0以降では、ウィンドウ関数内で ORDER BYを使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # ROW_NUMBER()でランキング付け&lt;br /&gt;
 SELECT&lt;br /&gt;
    name,&lt;br /&gt;
    salary,&lt;br /&gt;
    ROW_NUMBER() OVER (ORDER BY salary DESC) AS salary_rank&lt;br /&gt;
    FROM employees;&lt;br /&gt;
 &lt;br /&gt;
 # RANK()で同順位を考慮したランキング&lt;br /&gt;
 SELECT&lt;br /&gt;
    name,&lt;br /&gt;
    salary,&lt;br /&gt;
    RANK() OVER (ORDER BY salary DESC) AS salary_rank&lt;br /&gt;
    FROM employees;&lt;br /&gt;
 &lt;br /&gt;
 # DENSE_RANK()で連続したランキング&lt;br /&gt;
 SELECT&lt;br /&gt;
    name,&lt;br /&gt;
    salary,&lt;br /&gt;
    DENSE_RANK() OVER (ORDER BY salary DESC) AS salary_rank&lt;br /&gt;
    FROM employees;&lt;br /&gt;
 &lt;br /&gt;
 # パーティション内でのソート&lt;br /&gt;
 SELECT&lt;br /&gt;
    name,&lt;br /&gt;
    department_id,&lt;br /&gt;
    salary,&lt;br /&gt;
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_rank&lt;br /&gt;
    FROM employees;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ウィンドウ関数を使用することにより、グループごとのランキングや累積計算等が可能になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== GROUP BY ASC/DESC構文の廃止 ====&lt;br /&gt;
MySQL 8.0.13以降、GROUP BY句でのASC / DESC構文は廃止された。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # MySQL 8.0.12以前 (非推奨)&lt;br /&gt;
 SELECT department_id, COUNT(*) FROM employees&lt;br /&gt;
    GROUP BY department_id ASC;&lt;br /&gt;
 &lt;br /&gt;
 # MySQL 8.0.13以降 (エラー)&lt;br /&gt;
 # ERROR: &amp;#039;GROUP BY ASC/DESC&amp;#039; is not supported&lt;br /&gt;
 &lt;br /&gt;
 # 代わりにORDER BY句を使用&lt;br /&gt;
 SELECT department_id, COUNT(*) FROM employees&lt;br /&gt;
    GROUP BY department_id&lt;br /&gt;
    ORDER BY department_id ASC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;GROUP BY&amp;lt;/code&amp;gt; 句でソートが必要な場合は、明示的に &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; 句を使用する必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== インクリメンタルソートバッファ割り当て ====&lt;br /&gt;
MySQL 8.0.12以降、ソートバッファは増分割り当て (incremental allocation) される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
以前のバージョンでは、&amp;lt;code&amp;gt;sort_buffer_size&amp;lt;/code&amp;gt; で指定されたサイズのバッファが最初に確保されていた。&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0.12以降では、実際に必要なサイズのみが段階的に割り当てられるため、メモリ使用量が削減される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、&amp;lt;code&amp;gt;sort_buffer_size&amp;lt;/code&amp;gt; を大きな値に設定しても、メモリの無駄が発生しにくくなった。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:MySQL]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>