ORDER BY句のポイント6つと使い方|Then Byについても解説
- システム
エンジニア - LINQ機能ってなんだか難しそうですが、やっぱり使わないとダメなのでしょうか?
- プロジェクト
マネージャー - LINQ機能は初心者の方にとっては難しく感じるかもしれませんね。でも慣れてくると使い勝手がいい機能になりますよ。簡単にデータに問い合わせできるので、プログラム全体の質も上がってきます。
LINQ機能におけるORDER BY句を利用してのデータの並び替えとは
データベースに問い合わせを行ったことがある方なら、ORDER BY句で連想されるのはデータの並び替えではないでしょうか。LINQ機能でもORDER BY句を利用するとデータを並び替えることができます。
LINQではメソッド構文(ラムダ式を使用)とクエリ構文といった二通りの構文の書き方があります。
以下、クエリ構文を利用したLINQの基本形です。ORDER BY句は、Where句とSelect句の間にコーディングします。
1
2
3
4
5
|
クエリの結果を格納する変数 =
from データ変数 in データの集合
where 抽出条件
orderby 抽出順序のキー項目
select 抽出するメンバーで構成される新しいクラス ;
|
以下、メソッド構文でLINQ機能を利用した時に、ORDER BY句と同様にデータを並び替えることが可能なメソッドです。
OrderBy句 | 昇順ソートを行います。 |
---|---|
OrderByDescending句 | 降順ソートを行います。 |
ThenBy句 | 昇順ソートを行います。ソート条件を複数つけたい場合などで利用します。 |
ThenByDescending句 | 降順ソートを行います。ソート条件を複数つけたい場合などで利用します。 |
ORDER BYのポイント6つ
ここからは、C#のLINQ機能でORDER BY句を利用する際のポイントを6つほど紹介していきます。
MySQLやOracle SQLなど、SQLを使用してデータベースにアクセスしたことがあれば見覚えのあるものばかりでしょう。
ただし、SQLとは違いますのでご注意ください。このページを最後まで読んで、よく意味を理解してください。
1:基本構文
まずは基本となる構文を見ていきましょう。
基本的な構文は次の通りです。
1
2
3
4
5
6
7
|
クエリの結果を格納する変数 =
from データ変数 in データの集合
where 抽出条件
orderby 抽出順序のキー項目
select 抽出するメンバーで構成される新しいクラス ;
|
わかりやすいように例を用いて説明していきましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int[] prices = {100, 500, 50, 1, 10};//配列を作成
//クエリを作成
var query = //クエリの結果を格納する変数
from price in prices //データ変数 in データの集合
select price; //抽出するメンバーで構成される新しいクラス
//クエリの結果を出力
foreach (int p in query){
Console.WriteLine(p); //出力結果: 100 500 50 1 10
}
|
ここではpricesという配列を、クエリ構文を使用してそのまま表示させています。
これだけだとLINQを使うメリットがわからないと思いますので、次からORDER BY句やWhere句を使用して、並べ替えや抽出条件を追加していきます。
2:ASCを使った昇順の指定方法
先ほどの基本構文にORDER BY句を追加してみましょう。「orderby ~ ascending」で昇順に並べ替えることができます。
ORDER BY句はデフォルトで昇順になれべ替えるため、「ascending」は省略しても問題ありません。「orderby」の後ろに記載した値で順番を指定できます。
1
2
3
4
5
6
7
8
9
|
//クエリを作成
var query =
from price in prices
orderby price ascending//抽出順序のキー項目
select price;
//出力結果: 1 10 50 100 500
|
3:DESCを使った降順の指定方法
逆に降順で並び替えたい場合は、orderbyの後ろに「descending」を追加することで逆順になります。
さっそく使ってみましょう。
1
2
3
4
5
6
7
8
|
var query =
from price in prices
orderby price descending
select price;
//出力結果: 500 100 50 10 1
|
4:複数の要素をカンマ区切りでソートする場合
今度は複数の要素を使ってソートをしていきます。
例えば、硬貨の枚数と金額でソートした場合を考えてみましょう。
次のコードは硬貨の枚数が少ない順で、枚数が同じだった場合は硬貨の金額が高い順で並べ替えています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
var coins = new[] {
new {price = "100", num = "4"},
new {price = "500", num = "2"},
new {price = "50", num = "2"},
new {price = "1", num = "8"},
new {price = "10", num = "4"},
}
var query =
from coin in coins
orderby coin.num ascending, coin.price descending
//クエリの結果を出力
foreach (int p in query){
Console.WriteLine(p.price); //出力結果: 500 50 100 10 1
}
|
5:WHERE句を付けて条件を指定する方法
WHERE句を使って特定の条件を指定してみましょう。
次の例は、priceが100未満を条件にしています。
1
2
3
4
5
6
7
8
9
10
11
|
int[] prices = {100, 500, 50, 1, 10};//配列を作成
//クエリを作成
var query =
from price in prices
where price < 100 //抽出条件
select price;
//出力結果:50 1 10
|
今回は数値に対しての条件でしたが文字列を指定してあげることも可能です。また、複数条件で抽出することも可能です。
6:GROUP BYを付けてグループ化を行う方法
続いてはGROUP BY句の説明になります。
Group by句は今まではと少し毛色が異なるため分かりづらいでしょう。
やっていることはシンプルなのですぐに理解できるでしょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
var Employee_list = new[] {
new {no = "2021001", fname = "太郎", lname = "佐藤", department = "人事部"},
new {no = "2021002", fname = "花子", lname = "佐藤", department = "総務部"},
new {no = "2021003", fname = "寿郎", lname = "鈴木", department = "営業部"},
new {no = "2021004", fname = "加奈", lname = "鈴木", department = "開発部"},
new {no = "2021005", fname = "次郎", lname = "田中", department = "企画部"},
new {no = "2021006", fname = "恵子", lname = "中島", department = "総務部"},
new {no = "2021007", fname = "三郎", lname = "中野", department = "管理部"},
new {no = "2021008", fname = "吾郎", lname = "畠山", department = "人事部"},
new {no = "2021009", fname = "麻衣", lname = "浜田", department = "営業部"},
new {no = "2021010", fname = "妹子", lname = "山田", department = "営業部"},
};
var department_list =
from employee in Employee_list
group employee by employee.department
foreach(var department in department_list) {
Console.WriteLine(department.Key);
foreach(var emp in department_list) {
Console.WriteLine("{0} {1}", emp.lname, emp.fname
}
}
/*
出力結果:
人事部
佐藤 太郎
畠山 吾郎
総務部
佐藤 花子
中島 恵子
営業部
鈴木 寿郎
浜田 麻衣
山田 妹子
開発部
鈴木 加奈
企画部
田中 次郎
管理部
中野 三郎
*/
|
LINQ機能におけるORDER BY句の使用方法
ここでは、LINQ機能でのORDER BY句の活用例をメソッド構文とクエリ構文に分けて紹介していきます。
メソッド構文で書くLINQでの活用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
ublic void Test(Form1 form)
{
using (PubsDataContext pubs = new PubsDataContext())
{
var employees = pubs.employee.OrderBy(e => e.job_lvl)
.ThenBy(e => e.lname)
.Select(e => new
{
e.job_lvl,
e.lname,
e.fname,
e.emp_id
});
form.dataGridView1.DataSource = employees;
}
}
|
クエリ構文で書くLINQでの活用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public void Test(Form1 form)
{
using (PubsDataContext pubs = new PubsDataContext())
{
var employees = from e in pubs.employee
orderby e.job_lvl , e.lname
select new
{
e.job_lvl,
e.lname,
e.fname,
e.emp_id
};
form.dataGridView1.DataSource = employees;
}
}
|
ORDER BY句以外で並び替えできるもの
ここからはThen By句の使用方法を説明していきます。
Then by 句はORDER BY句で並び替えた結果に対してさらに並び替えを行いたい場合に使用します。Then by句単体での使用はできませんので、ご注意ください。
Then By句
これまで通り、例を挙げていきます。
Then By句はORDER BY句の後ろにつけてあげましょう。Then By句で指定することでORDER BY句で同値だったものについてもソートの条件を指定することが可能です。
ORDER BY句を使用して、複数要素での並び替えを行った際のコードを書き換えてみましょう。
硬貨の枚数で昇順にソートした結果に対して、硬貨の金額で昇順にソートします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var coins = new[] {
new {price = "100", num = "4"},
new {price = "500", num = "2"},
new {price = "50", num = "2"},
new {price = "1", num = "8"},
new {price = "10", num = "4"},
}
var query =
coins
.OrderBy(coin => coin.num)
.ThenBy(coin => coin.price);
//クエリの結果を出力
foreach (int p in query){
Console.WriteLine(p.price); //出力結果: 50 500 10 100 1
}
|
Then By Descending句
先ほどはThen By句を使用して昇順に並び替えるやり方を見たので、今度は反対にThen By Descending句の使い方を見ていきましょう。
先ほどと同様にORDER BY句の後ろにThen By Descending句をつけましょう。
Then By Descending句を使用することで、昇順と降順の並び替えを組み合わせることが可能になります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var coins = new[] {
new {price = "100", num = "4"},
new {price = "500", num = "2"},
new {price = "50", num = "2"},
new {price = "1", num = "8"},
new {price = "10", num = "4"},
}
var query =
coins
.OrderBy(coin => coin.num)
.ThenByDescending(coin => coin.price);
//クエリの結果を出力
foreach (int p in query){
Console.WriteLine(p.price); //出力結果: 500 50 100 10 1
}
|
DISTINCTとORDER BYを併用するときの注意点
DISTINCT句は重複したデータを省略するのにとても便利ですが、OORDER BY句と併用する際には2点ほど注意が必要です。ここでは注意点を説明していこうと思います。
1:DISTINCTとORDER BYの使用順序
DISTINCTとORDER BYを併用する際、記載する順番を誤ると想定通りの結果が得られなくなるため注意が必要です。
例えば次の例を見てみましょう。
ORDER BYで降順に並び替えた結果に対して、DISTINCTで重複した複数の値をなくし結果を表示していますが、ORDER BY句が効かないため出力結果は降順になっていません。
1
2
3
4
5
6
7
8
9
10
|
int[] prices = {100, 500, 50, 1, 10, 100, 1, 10};
var query =
prices
.OrderByDescending(price => price)
.Distinct();
//出力結果: 1 10 50 100 500
|
最終的に降順に並び替えた結果が欲しい場合はDistinctの後にOrder By句を使用する必要があります。
1
2
3
4
5
6
7
8
9
10
|
int[] prices = {100, 500, 50, 1, 10, 100, 1, 10};
var query =
prices
.Distinct()
.OrderByDescending(price => price);
//出力結果: 500 100 50 10 1
|
DISTINCT使用時にSELECTに含まれない項目の並べ替え
また、DISTINCTとORDER BYを併用する際は、DINSTINCT句をSELECT文に指定する場合、ORDER BYではSELECTのリストに含まれていない項目を並び替えに使用できないため注意しましょう。
- システム
エンジニア - OrderBy句やWhere句などSQLを利用したことがある方なら見覚えのある単語がけっこうLINQ機能には出てきますが、LINQとSQLは同じなのでしょうか?
- プロジェクト
マネージャー - LINQとSQLは全くの別物ですよ。 C#独自の構文ですのでSQLとは混在しないようにしましょうね!
ORDER BY句を活用して並び順を保障しよう
こまでC#のLINQでORDER BY句について説明してきました。
最初に挙げた基本形を見直してみましょう。
1
2
3
4
5
6
7
|
クエリの結果を格納する変数 =
from データ変数 in データの集合
where 抽出条件
orderby 抽出順序のキー項目
select 抽出するメンバーで構成される新しいクラス ;
|
いかがでしょうか。最初に読んだときはよく分からなかった構文も理解できるようになっているのではないでしょうか。ORDER BY句を使用しない場合、必ずしも表示順が一致するとは限りません。
思わぬバグを引き起こさないためにも、ORDER BY句を使用して並び順を保証してあげましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
新着案件New Job
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅) -
PMO/東京都豊島区/【WEB面談可】/在宅勤務
月給55万~55万円東京都豊島区(池袋駅)