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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

Q&A

解決済

6回答

49705閲覧

【mysql】case文で条件に一致したら複数項目取得したい

k499778

総合スコア599

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

0グッド

0クリップ

投稿2016/08/01 10:17

現在mysqlでデータ取得のコードを書いています。

質問があるのですが、
結論からいうと、

case文で条件に一致したら複数項目を取得するにはどのうようにすればいいでしょうか?

具体的な状況は次のとおりです。

料理テーブルに「食べ物フラグ」カラムがあり、1だと「野菜」、2だと「フルーツ」「お菓子」カラムを取得します。

そこでcase文を使って書こうとしているのですが、複数取得の方法がわかりません。

select
case 食べ物フラグ
when '1' then 野菜
when '2' then フルーツ,お菓子
else null
end
from 料理テーブル

のような書き方はできますでしょうか?

もしできないようであれば他の方法を教えていただけると助かります。

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

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

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

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

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

A.Ichi

2016/08/01 11:09

確認ですが、食べ物フラグの値が1の時、項目(野菜)の値を表示し、2の時は項目(フルーツ)と項目(お菓子)を表示すると言う意味でしょうか?
k499778

2016/08/01 12:40

そうです
guest

回答6

0

すでにベストアンサーが出てますが

UNION ALLで1レコードごとに取得して
表示側で縦でも横でも好きなように表示できるようにしたらいいんじゃないでしょうか?

SQL

1SELECT 野菜 2FROM 料理テーブル 3WHERE 取得条件 4AND 野菜フラグ = 1 5UNION ALL 6SELECT フルーツ 7FROM 料理テーブル 8WHERE 取得条件 9AND 野菜フラグ = 2 10UNION ALL 11SELECT お菓子 12FROM 料理テーブル 13WHERE 取得条件 14AND 野菜フラグ = 2 15

投稿2016/08/02 05:10

kutsulog

総合スコア985

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

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

k499778

2016/08/02 22:44

回答ありがとうございます。 確かにこれだと出力できますね!勉強になりました。 ありがとうございます。
guest

0

ネタ系SQLとすればこのあたりだね

sql

1SELECT 2 (CASE WHEN 食べ物 = 1 THEN 野菜 3 WHEN 食べ物 = 2 THEN 果物 4 ELSE NULL END) AS ITEM_1, 5 (CASE WHEN 食べ物 = 2 THEN 菓子 6 ELSE NULL END) AS ITEM_2 7FROM 8 テーブル名 9WHERE 10 条件式

投稿2016/08/01 12:54

asahina_dev

総合スコア610

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

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

k499778

2016/08/01 13:08

回答ありがとうございます。 頑張ればそういう方法でもできるのですね!いろいろと勉強になります。 他の方にも聞いているのですが、 そもそもなぜこんなことを聞いているかというと、 現在詳細設計をしていて 「食べ物フラグが1のときは野菜項目を表示し、食べ物フラグが2のときはフルーツ項目、お菓子項目を表示する」という仕様があるのです。 まだまだ経験が浅い私なのですが、それはSQLでどうにかするよりも普通画面側(HTML側)で条件分岐をかまして表示するっていう方が自然なのですかね? フラグも項目も全取得して。SQLでどうにかするのではなく、画面側で。 テンプレートエンジンにタイムリーフを導入しているのでそのようなこともできると思いますし。 もしお時間ございましたらご意見お聞かせ願えればと思います。
asahina_dev

2016/08/01 13:13

回答でもいってるとおり SQLでやるのは「ネタ」です。 通常は画面(VIEW)ですね
k499778

2016/08/01 13:15

返答頂きありがとうございます。 そうですよね。それに気づかせていただくことができました。 ありがとうございました。
guest

0

回答出揃ってるので蛇足ですが…

提示されてるようなSQLは記載不可なのでいくつかの代替案で対処する必要があります。

###代替案について
要件次第で、
以下のアプローチのうちいずれかを取る形になるのかなと思います。

①CASE式内でCOALESCEを用いる
②結果の文字列を結合して取得する
③取得カラムを明示的に分ける

①が採用できる前提条件は、

  • どちらか一方の値だけが出力されることが許容できること(フルーツとお菓子は背反で取得される)
  • どちらか一方が優先出力されるのが許容できること(どちらも値がある場合は片方が優先取得される)

③が採用できる条件は、

  • 出力結果としてカラムが増えることが許容できること(個人的には結果を混ぜるよりはカラムは分けてた方がメンテしやすい気はします)

出力の仕方は区分値に該当するなら登録値、なければNULLとか空文字とか…

②については上記2つの選択肢が取れない場合に採用する手段かなと思います。

コードは他の方の分で出揃ってるかなと思いますので当方からの掲示は割愛します。

###おまけの話
上記のようなシチュエーションは、
1度限りとかであれば特殊要件なので、あまり心配しなくて良いかと思いますので以下読み飛ばしてください。

ですが万一同じような処理が、
色々な機能で必要となるんですよという状況であれば、テーブル構造の見直しが一番の最適解になることもあり得ます。

SQLやPGでごちゃごちゃしなければな
らないケースというのは、
テーブル構造の歪みに起因することもしばしばです。

やりたいこととして提示していただいてるサンプルを見る限り、
フルーツとお菓子の区別がテーブル保存時に消えてしまっているように見受けられます。

データベースとのやりとりの複雑度は、
こういった情報の欠落が起これば起こるほど飛躍的に上がるものなので、
もし今回のような処理ケースが今後も出てくる、あるいは既に散在しているのでしたら、テーブル定義の見直しを進言しても良いかもしれません。

個人的には食べ物区分は種別ごとに一意に振られ、
でもフルーツとお菓子どっちも取ってこないいけないよという要件があるなら、
もう一個それを示すフラグとか区分なりを追加する方が後々すっきりするかなとも思ってます。

###補足
CASE式について補足。
THEN句の後の値のデータ型が一致することが要求されます。

以下は文字列の場合

SQL

1CASE col1 2 WHEN '1' THEN '文字列1' 3 WHEN '2' THEN '文字列2' -- 一つ目文字なら2つ目も文字で統一 4 ELSE NULL -- ただしNULLはOK 5END

以下は数値

SQL

1CASE col1 2 WHEN '1' THEN 100 3 WHEN '2' THEN 5 -- 一つ目数値なら2つ目も数値で統一 4 ELSE NULL -- ただしNULLは(ry 5END

投稿2016/08/01 12:16

編集2016/08/01 12:42
Panzer_vor

総合スコア1636

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

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

k499778

2016/08/01 12:51

回答有り難うございます。 ご回答いただいた中に「取得カラムを明示的に分ける」というのがあるのですが、 こちらはどのようにするのでしょうか? もしかすると私がcase文と言ってしまったから逆にミスリードしてしまったかもしれません。 結果を混ぜるよりむしろカラムを分けて取得したいと思っています。 結果として 「食べ物フラグ」が1のとき、「野菜」の項目が、「食べ物フラグ」が2のとき、「フルーツ」の項目と「お菓子」の項目を取得したいと思っています。 なのでcase文にこだわりはなく、目的を達成できればやり方はなんでも大丈夫です。 それでもやはりそのようなことはできないのでしょうか?
Panzer_vor

2016/08/01 12:58

yambejpさんの4つ目のSQLが参考となります。 後、asahina_devさんのでも実現できそうですね。
k499778

2016/08/01 13:17

回答有り難うございます。 SQLでもがんばれば実現できるとわかりました。 ただ画面側で編集するという視点に気づくことができ、SQLでは前取得し、Viewで編集する方向で行きたいと思います。 貴重なご意見ありがとうございました。 また一歩進むことができました。感謝しています。
guest

0

ベストアンサー

まず命題のSQLは不可能です

代替案として

SQL

1create table 料理テーブル(id int not null primary key,野菜 varchar(20) null,フルーツ varchar(20) null,お菓子 varchar(20) null,食べ物フラグ tinyint); 2insert into 料理テーブル values(1,'にんじん',null,null,1),(2,'じゃがいも',null,'じゃがりこ',1),(3,'きゅうり','きゅうり',null,2),(4,null,null,'きのこの山',2),(5,null,'バナナ','バナナ',2),(6,null,null,null,0);

に対して複数項目を得るときにはCONCATでひろうとか

SQL

1select 2case 食べ物フラグ 3when 1 then 野菜 4when 2 then CONCAT(COALESCE(フルーツ,''),',',COALESCE(お菓子,'')) 5else null 6end AS 食べ物 7from 料理テーブル;

しかしこれだとどちらかにしかデータがない場合中途半端なカンマがつくので
気持ち悪い、たとえばどちらか取ればいいなら

SQL

1select 2case 食べ物フラグ 3when 1 then 野菜 4when 2 then COALESCE(フルーツ,お菓子) 5else null 6end AS 食べ物 7from 料理テーブル;

もしくは視点を変えてカラムは表示するけどNULLにするとか

SQL

1select if(食べ物フラグ=1,野菜,null) AS 野菜 2,if(食べ物フラグ=2,フルーツ,null) AS フルーツ 3,if(食べ物フラグ=2,お菓子,null) AS お菓子 4,食べ物フラグ 5from 料理テーブル;

投稿2016/08/01 11:11

yambejp

総合スコア114784

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

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

yambejp

2016/08/01 13:06

レコードごとに列数が変わることはSQLでもエクセルでもテーブルでも どう考えてもありえませんよね? 上記例を利用した場合どういう結果がほしいのか提示してみてください ご自身が頭のなかで架空の結果を得ている可能性が高い
k499778

2016/08/01 13:07

回答ありがとうございます。 いろいろな方法があることが知れて本当に良かったです。 他の方にも聞いているのですが、 そもそもなぜこんなことを聞いているかというと、 現在詳細設計をしていて 「食べ物フラグが1のときは野菜項目を表示し、食べ物フラグが2のときはフルーツ項目、お菓子項目を表示する」という仕様があるのです。 まだまだ経験が浅い私なのですが、それはSQLでどうにかするよりも普通画面側(HTML側)で条件分岐をかまして表示するっていう方が自然なのですかね? フラグも項目も全取得して。SQLでどうにかするのではなく、画面側で。 テンプレートエンジンにタイムリーフを導入しているのでそのようなこともできると思いますし。 もしお時間ございましたらご意見お聞かせ願えればと思います。
yambejp

2016/08/01 13:10

必要項目を得るということは、不必要項目を得ないということと同意ではありません。 必要項目が列記されていれば、うけとったプログラム側で必要に応じて 任意の項目を取得すればよいのです。
k499778

2016/08/01 13:13

タイムラグが発生してしまい、コメント頂く前に返答してしまいました。 そして今頂いたコメントで私は大きな気づきをすることができました。 そういうことですよね! 勝手にその仕様を見てSQLで条件分岐をしようとしていました。 全取得してプログラム側で編集するような設計に致します。 大変親身に回答していただきありがとうございました。また一歩成長することができました。ありがとうございます。SQLも勉強します。
guest

0

MySQL

1select 2case 食べ物フラグ 3when '1' then 野菜 4when '2' then concat(ifnull(フルーツ, ''), ifnull(お菓子, '')) 5else null 6end 7from 料理テーブル

こういうことかしら?

投稿2016/08/01 11:08

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

k499778

2016/08/01 13:05

回答有り難うございます。 私も最終手段としてconcatで文字連結する手も考えていました。 アドバイス頂き感謝です。 他の方にも聞いているのですが、 そもそもなぜこんなことを聞いているかというと、 現在詳細設計をしていて 「食べ物フラグが1のときは野菜項目を表示し、食べ物フラグが2のときはフルーツ項目、お菓子項目を表示する」という仕様があるのです。 まだまだ経験が浅い私なのですが、それはSQLでどうにかするよりも普通画面側(HTML側)で条件分岐をかまして表示するっていう方が自然なのですかね? フラグも項目も全取得して。SQLでどうにかするのではなく、画面側で。 テンプレートエンジンにタイムリーフを導入しているのでそのようなこともできると思いますし。 もしお時間ございましたらご意見お聞かせ願えればと思います。
guest

0

where で食べ物フラグの条件を指定して、
各々のレコードを取得して
union all したら?
--- 追加 ---

yambejpさんの回答を見てなるほど!って思った。
ちなみに、自分はこんな感じで考えてた。

SQL

1select 野菜 as item1,null as item2 from 料理テーブル where 食べ物フラグ=1 2union all 3select フルーツ as item1,お菓子 as item2 from 料理テーブル where 食べ物フラグ=2

投稿2016/08/01 11:03

編集2016/08/01 11:28
takasima20

総合スコア7458

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

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

k499778

2016/08/01 13:04

回答有り難うございます。 まだまだSQL初心者で初歩的な質問をしてしまい申し訳ないです。 union all という手もあるのですね!参考になります。 そもそもなぜこんなことを聞いているかというと、 現在詳細設計をしていて 「食べ物フラグが1のときは野菜項目を表示し、食べ物フラグが2のときはフルーツ項目、お菓子項目を表示する」という仕様があるのです。 まだまだ経験が浅い私なのですが、それはSQLでどうにかするよりも普通画面側(HTML側)で条件分岐をかまして表示するっていう方が自然なのですかね? フラグも項目も全取得して。SQLでどうにかするのではなく、画面側で。 テンプレートエンジンにタイムリーフを導入しているのでそのようなこともできると思いますし。 もしお時間ございましたらご意見お聞かせ願えればと思います。
takasima20

2016/08/01 13:21

そもそも的な話なら、KotoriMaturiさんが指摘されているように 「なんでそんなテーブルになってんの?」ってとこですよね。 何某かの意図があってそういう造りになっているのなら、 それに沿った処理の仕方はおのずと決まってくるでしょう。 で、それは部外者の我々では分からないってことです。 技術的に、一般的にどういう方法があるかってのは いくらでも提示できますが、それが「そもそも」の方針に 合致していなければ混乱を生むだけでしょう。 いますべきなのは、ここに質問することではなく データベースの設計者と話すことだと思います。 ちなみに、自分だったら素直に全項目を(SQLで)取得して プログラム側でいいようにする方法をとるかなあ。
k499778

2016/08/01 13:27

返答ありがとうございます。 そうなんですね。あまりないテーブル構造なのでしょうか。 自分自身まだまだそういうところに気づけるレベルではないので仕様通り落とし込んでいました。 ただプログラム側で行うのが一般的のようですね。 takasima20さんもおっしゃっている通りそのようにして進めていきたいと思います。 アドバイス頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問