質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

2722閲覧

SQL:ORDER BY CASE ~ でNプレフィックスを使用している意味

mahry

総合スコア37

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/08/29 04:14

SQLについて学んでいるのですが、
ORDER BY で複数指定できることはわかったのですが、

SQL

1ORDER BY CASE WHEN ○○ IS NOT NULL THEN N'000' ELSE ×× END , △△

上記のように、Nプレフィックスがあることで一体何が起きているのか、
参考書等を読み返したのですがその記述がなく、
理解することができません。

例えば
|Id|CompanyId|ReceiptCategoryId|RecordedAt|ReceiptAmount|ReceiptAccountCode|ReceiptBanckCode|ReceiptBranchCode
|:--|:--:|--:|
|1|0001|11|2019-01-31|1,250|11002|001|901
|2|0001|12|2019-01-31|82,116|11002|001|901
|3|0002|35|2019-01-31|14,038|12001|005|501
|4|0002|15|2019-01-31|5,997|12004|004|401
|5|0002|23|2019-01-31|3,208|12015|009|909
|6|0002|5|2019-01-31|60,001|12097|008|801

というようなテーブル[Receipt]があるとします。
これをORDER BY句とCASE句を使用して任意のソート順にするとき、
(任意のソート:ReceiptCategoryId = 15 のものを一番上に持っていきたい、それ以外はReceiptBrachCode順)

SQL

1SELECT 2 Id 3, CompanyId 4, ReceiptCategoryId 5, RecordedAt 6, ReceiptAmount 7, ReceiptAccountCode 8, ReceiptBankCode 9, ReceiptBranchCode 10FROM 11TBL_Receipt 12WHERE CompanyId = '0002' 13ORDER BY 14CASE WHEN ReceiptCategoryId = 15 THEN 1 15ELSE ReceiptBranchCode END ,ReceiptBankCode

上記の実行結果
|Id|CompanyId|ReceiptCategoryId|RecordedAt|ReceiptAmount|ReceiptAccountCode|ReceiptBanckCode|ReceiptBranchCode
|:--|:--:|--:|
|4|0002|15|2019-01-31|5,997|12004|004|401
|3|0002|35|2019-01-31|14,038|12001|005|501
|6|0002|5|2019-01-31|60,001|12097|008|801
|1|0001|11|2019-01-31|1,250|11002|001|901
|2|0001|12|2019-01-31|82,116|11002|001|901
|5|0002|23|2019-01-31|3,208|12015|009|909

となると思います。
ここまでは問題ないです。理解できていると思っています。

問題なのは、下記のような場合です。

SQL

1SELECT 2 Id 3, CompanyId 4, ReceiptCategoryId 5, RecordedAt 6, ReceiptAmount 7, ReceiptAccountCode 8, ReceiptBankCode 9, ReceiptBranchCode 10FROM 11TBL_Receipt 12WHERE CompanyId = '0002' 13ORDER BY 14CASE WHEN ReceiptCategoryId IS NOT NULL THEN N'000' 15ELSE ReceiptBranchCode END ,ReceiptBankCode

ReceiptCategoryIdがNULL値ではないときに指定されているNプレフィックスが持つ意味がわかりません。

SQL

1ORDER BY CASE WHEN ReceiptCategoryId IS NOT NULL THEN ReceiptCategoryId ELSE ReceiptBranchCode END

(↑ReceiptCategoryIdがNULL値ではなかったとき、ReceiptCategoryId順、NULL値だったらReceiptBranchCode順)
上記ではダメな理由がわかりませんでした。
教えていただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Nプレフィックスは単にUnicodeを指定しているだけです。
この場合のうまくいかない原因ではありません。

それよりも問題なのは型を無視していることです。
まず、ReceiptCategoryId と ReceiptBranchCode の型を意識する必要があります。
次に、ORDER BY句では比較を行うため型を合わせる必要があります。
自動変換してくれる場合もありますが、意図しない結果になることが少なからず発生します。

ReceiptCategoryId はおそらく数値型なのでしょう。
Nプレフィックスを付けていると言うことはReceiptBranchCodeはUnicode文字列なのでしょう。
NOT NULLのときN'000'とすることで正しくUnicode文字列どうしの比較が行えます。

CASE WHEN ReceiptCategoryId = 15 THEN 1 ELSE ReceiptBranchCode END

ここまでは問題ないです。理解できていると思っています。

問題があります。
ReceiptBranchCodeに0から始まる値がなかったので、たまたまうまく行っただけです。
この場合も1ではなくN'000'などにする必要があります。

投稿2019/08/29 05:24

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mahry

2019/08/29 06:21

ご回答ありがとうございます。 とても分かりやすくて、理解できました。 ありがとうございます。
guest

0

上記のように、Nプレフィックスがあることで一体何が起きているのか、

文字列をUnicodeとして扱っているだけです。
https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/constants-transact-sql?view=sql-server-2017#unicode-strings

投稿2019/08/29 04:42

gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mahry

2019/08/29 06:21

ご回答ありがとうございます。 リンク先を読みました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問