<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL &#8211; エンジニア見習い</title>
	<atom:link href="https://otonan-syusyoku.work/archives/category/learning/sql/feed" rel="self" type="application/rss+xml" />
	<link>https://otonan-syusyoku.work</link>
	<description>三流プログラマー</description>
	<lastBuildDate>Wed, 14 Aug 2024 13:05:52 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://otonan-syusyoku.work/wp-content/uploads/2023/10/cropped-名称未設定のデザイン-16-32x32.png</url>
	<title>SQL &#8211; エンジニア見習い</title>
	<link>https://otonan-syusyoku.work</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【設定しましょう】RDS for MySQL のパラメータグループ</title>
		<link>https://otonan-syusyoku.work/archives/1829</link>
					<comments>https://otonan-syusyoku.work/archives/1829#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 14 Aug 2024 05:36:57 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1829</guid>

					<description><![CDATA[RDS新規立ち上げ時に default パラメータグループを設定している方が多いと思うのですが、default パラメータグループだと色々まずい問題があるのでそれやめましょうというお話をさせて頂ければと思います。 Con [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>RDS新規立ち上げ時に default パラメータグループを設定している方が多いと思うのですが、default パラメータグループだと色々まずい問題があるのでそれやめましょうというお話をさせて頂ければと思います。</p>
<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="1829" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">困った話</a></li><li class="rtoc-item"><a href="#rtoc-2">最低限の設定値</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-3">max_execution_time</a></li><li class="rtoc-item"><a href="#rtoc-4">general_log</a></li><li class="rtoc-item"><a href="#rtoc-5">slow_query_log</a></li><li class="rtoc-item"><a href="#rtoc-6"><span>long_query_time</span></a></li></ul></li></ol></div><h2 id="rtoc-1" >困った話</h2>
<p>slow-query が検出できなくて困ったなぁと言うのが事の発端です。</p>
<p>考えてみると<span class="sc_marker blue"><strong>AWSさんが用意してくれたとりあえずdefaultパラメータを当てておけば問題ない</strong></span> だろうと考えてしまっていたのが大問題でした。</p>
<p>プロジェクトごとにDB周りの設定は変わってくるのは当たり前の話なので、自分のプロジェクトにとって必要な設定値を用意しなかった自分が100%悪いです。</p>
<p>反省です。</p>
<h2 id="rtoc-2" >最低限の設定値</h2>
<h3 id="rtoc-3" >max_execution_time</h3>
<h4>概要</h4>
<p><span>ミリ秒単位での SELECT ステートメントの実行タイムアウト</span></p>
<h4>値</h4>
<p>ミリ秒になるので <strong>指定したい秒数*1000 </strong>を指定してあげると良い。</p>
<p>例）60秒で切りたい<br />
60 * 1000 = 60000</p>
<h3 id="rtoc-4" >general_log</h3>
<h4>概要</h4>
<p>一般ログの出力</p>
<h4>値</h4>
<p>1に設定しましょ</p>
<h3 id="rtoc-5" >slow_query_log</h3>
<h4>概要</h4>
<p>slow query のログを出力するか否か</p>
<h4>値</h4>
<p>1に設定しましょ。これで出力するという意味になるよ</p>
<h3 id="rtoc-6" ><span>long_query_time</span></h3>
<h4>概要</h4>
<p><span>ログに記録されるクエリの最短実行時間の値を設定することが出来る。<br />
この値を超えるとslow</span></p>
<h4>値</h4>
<p>基本的に `max_execution_time` より小さくしましょう。検出できなくなるので。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1829/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL学んで気づいたことを紹介するョ</title>
		<link>https://otonan-syusyoku.work/archives/1093</link>
					<comments>https://otonan-syusyoku.work/archives/1093#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 09 Mar 2022 06:00:47 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1093</guid>

					<description><![CDATA[Contents 気づいたこと　〜就職編〜結局SQLインフラにもバックエンドにも気をつけること　〜考え方編〜実行順序書き方は十人十色データは超重要気づいたこと　〜書き方編〜インデントは揃えよう予約文字は大文字目的を考える [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="1093" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">気づいたこと　〜就職編〜</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-2">結局SQL</a></li><li class="rtoc-item"><a href="#rtoc-3">インフラにもバックエンドにも</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-4">気をつけること　〜考え方編〜</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-5">実行順序</a></li><li class="rtoc-item"><a href="#rtoc-6">書き方は十人十色</a></li><li class="rtoc-item"><a href="#rtoc-7">データは超重要</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-8">気づいたこと　〜書き方編〜</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-9">インデントは揃えよう</a></li><li class="rtoc-item"><a href="#rtoc-10">予約文字は大文字</a></li><li class="rtoc-item"><a href="#rtoc-11">目的を考える</a></li></ul></li></ol></div><h2 id="rtoc-1" >気づいたこと　〜就職編〜</h2>
<h3 id="rtoc-2" >結局SQL</h3>
<p>結局のところSQLは必要不可欠な技術です。</p>
<p>アプリケーションはPHPやJavaといったプログラミング言語を使用すると思いますが、データを扱う事のできる唯一の言語はSQLです。</p>
<p>そのため、SQLが出来るだけで重宝されます。</p>
<p>[getpost id=&#8221;1028&#8243;]</p>
<h3 id="rtoc-3" >インフラにもバックエンドにも</h3>
<p>IT業界の職種はかなり広いのですが、SQLはインフラとバックエンドに領域が被っている為、就職の選択肢がかなり広がります。</p>
<p>最近ではフロントの人間もSQLを使用する事があるそうです。←僕の友達情報</p>
<p>そのため、僕の考えとしてはSQLを基盤に学ぶことでデータを扱えるIT人材になれるので、どこを目指したら良いのか分からない人はとりあえずSQLについて学ぶべきです。</p>
<p>[getpost id=&#8221;1045&#8243;]</p>
<h2 id="rtoc-4" >気をつけること　〜考え方編〜</h2>
<h3 id="rtoc-5" >実行順序</h3>
<p>実行順序の理解は大切です。</p>
<p>呼ばれる順序が分かることで、目的に沿ったSQL文を書くことが出来ます。逆に言うと<span class="sc_marker blue"><strong>実行順序を意識していなければ意図しないデータを取得する事になってしまいます。</strong></span></p>
<p>実行順は以下の通りです。</p>
<ol>
<li>FROM</li>
<li>WHERE</li>
<li>GROUP BY</li>
<li>HAVING</li>
<li>SELECT</li>
<li>DISTINCT</li>
<li>ORDER BY</li>
</ol>
<p>SQLを学習した当初は欲しいデータに意識が向きすぎてしまいSELECT句が重要だと考えていました。</p>
<p>しかし、本当に欲しいデータを取得する場合は<span class="sc_marker blue"><strong>大本のテーブルから考えていく必要があります。</strong></span></p>
<p><span class="sc_marker y">どのテーブルからどの条件でデータを取得していくのか</span>意識してみてください。</p>
<h3 id="rtoc-6" >書き方は十人十色</h3>
<p>早めの段階で知りたかったのですが、<span class="sc_marker blue"><strong>SQLの書き方は十人十色</strong></span>です。</p>
<p>&nbsp;</p>
<p>SQLを学びたての時は教科書通りに書かないといけないという意識が強く、柔軟性にかけたSQLを記述していました。(教科書通り→INはEXISTSで代替。サブクエリはできるだけ書かない。)</p>
<p>&nbsp;</p>
<p>しかし実業務でデータを扱う際にはこんな書き方は良くないよって言われている書き方で実装しているSQLはよく目にします。<br />
※1万レコードをUNIONで横持ちのデータを縦持ちに結合している仰天コードを目にしたことがあります。</p>
<p>&nbsp;</p>
<p><span class="sc_marker y">Aを取得するという目的に対して、こうした方が良いよねって言う書き方はあるけど、正解はありません。</span></p>
<p><span class="sc_marker blue"><strong>必要なデータを取得できないことが悪</strong></span>なので、慣れるまでは速さやキレイにデータを取得すると行った事は気にしないでおきましょう。</p>
<p>SQLに関しては知見が増えてくれば<span class="sc_marker blue"><strong>自然</strong><strong>とどのような記述が最適なのかが理解できてくるので少しづつ努力していけば問題なし</strong></span>です。</p>
<h3 id="rtoc-7" >データは超重要</h3>
<p>データなんかより画面動かしたりする方がITっぽくてカッコいい〜！なんて思っていたのですが、<span class="sc_marker blue"><strong>ビジネスに必要なものはデータ</strong></span>だと実務に入って気づきました。</p>
<p>&nbsp;</p>
<p>結局の所、<span class="sc_marker blue"><strong>データを自分たちの使いやすい形でデータを取得or加工し、お金を生み出す形でデータを利用しているのがWebサービスの根幹</strong></span>だと思います。</p>
<p>&nbsp;</p>
<p>データを扱えるって最強です。</p>
<h2 id="rtoc-8" >気づいたこと　〜書き方編〜</h2>
<h3 id="rtoc-9" >インデントは揃えよう</h3>
<p>SQLの経験が浅くても出来る事その1はインデントを揃えよう！です。</p>
<p>以下2つのSQL文を比較してもらえれば分かると思うのですが、格段に見やすさが異なると思います。</p>
<div class="row sp">
<div class="row sp">
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
WHERE no &gt; 4 
AND name IN ('aiueo','test') 
ORDER BY no;</code></pre>
</div>
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
 WHERE no &gt; 4 
      AND name IN ('aiueo','test') 
 ORDER BY no;</code></pre>
</div>
</div>
</div>
<p>&nbsp;</p>
<h3 id="rtoc-10" >予約文字は大文字</h3>
<p>SQLの経験が浅くても出来る事その1は予約文字は大文字で記述！です。</p>
<p>予約文字はSQLで設定されている単語の事を指します。<br />
(例：SELECT.FROM,WHERE,JOIN,)</p>
<p>こちらも比較してもらえれば分かると思います。</p>
<div class="row sp">
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">select no,name from test
where no &gt; 4
    and name in('aiueo','test')
order by no</code></pre>
</div>
<div class="sc_col2 sp">
<pre class="line-numbers"><code class="language-other">SELECT no , name FROM test 
 WHERE no &gt; 4
      AND name IN ('aiueo','test') 
 ORDER BY no;</code></pre>
</div>
</div>
<h3 id="rtoc-11" >目的を考える</h3>
<p>SQLに慣れてきたら何のデータが欲しいのかを考える癖をつけていきましょう。</p>
<p>SQLは様々な記述方法でデータを取得することが出来るため、目的を明確にし必要なデータを取得する事を意識してください。</p>
<p>目的を明確にすることで<span class="sc_marker blue"><strong>どの記述方法が最適なのか</strong></span>が段々と分かってくるはずです。</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1093/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>サブクエリの返答は単一行のみ！もしくは述語の指定が必要！</title>
		<link>https://otonan-syusyoku.work/archives/1004</link>
					<comments>https://otonan-syusyoku.work/archives/1004#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 16 Jan 2022 02:21:38 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1004</guid>

					<description><![CDATA[Contents 複数行を返すとエラーになりますサブクエリの結果を複数行受け取れる述語複数行を返すとエラーになります Where句で使用するサブクエリの問い合わせ結果が2行以上になってしまうと「single-row su [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="1004" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">複数行を返すとエラーになります</a></li><li class="rtoc-item"><a href="#rtoc-2">サブクエリの結果を複数行受け取れる述語</a></li></ol></div><h2 id="rtoc-1" >複数行を返すとエラーになります</h2>
<p>Where句で使用するサブクエリの問い合わせ結果が2行以上になってしまうと「single-row subquery returns more than one row」のエラーが帰ってきます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no = (select no from test); 
 where no = (select no from test)
             *
ERROR at line 2:
ORA-01427: single-row subquery returns more than one row</code></pre>
<p>サブクエリの結果が複数帰ってきてしまうと<span class="sc_marker blue"><strong>No列の比較にどの値を使用したら良いのか分からない為のエラー</strong></span>です。</p>
<p>そのため、サブクエリの帰ってくる値を単一にする必要があります。</p>
<p>サブクエリを使用する時はケースバイケースのため、その都度サブクエリの帰ってくる件数を意識しましょう。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt;  select * from test
 where no = (select no from test where no = 1);  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa</code></pre>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
  where no = (select max(no) from test);    

	NO NAME
---------- --------------------------------------------------
	 5 youo
</code></pre>
<h2 id="rtoc-2" >サブクエリの結果を複数行受け取れる述語</h2>
<p>もしサブクエリの帰ってくる件数を複数のときにしたい場合は「IN」や「EXISTS」、「ANY」などの述語を指定します。</p>
<p>これらの述語を使用することで<strong><span class="sc_marker blue">サブクエリの結果のどれかと一致するものを正とする事</span></strong>を表現することが出来ます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no IN(select no from test0);   

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo</code></pre>
<p>&nbsp;</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where exists(select no from test0 where test.no = test0.no);  2  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo</code></pre>
<p>&nbsp;</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from test
 where no = ANY(select no from test0);  2  

	NO NAME
---------- --------------------------------------------------
	 1 aaaaa
	 2 iiiii
	 2 uouoo
</code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1004/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>テーブル結合の名前が多すぎる！！からまとめたよ</title>
		<link>https://otonan-syusyoku.work/archives/995</link>
					<comments>https://otonan-syusyoku.work/archives/995#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sat, 15 Jan 2022 07:19:45 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=995</guid>

					<description><![CDATA[Contents 参考書を読んでも分かりづらい結合の種類2テーブルで結合を試していくぅ内部結合外部結合(左外部結合、右外部結合)完全外部結合自己結合クロス結合自然結合非等価結合参考書を読んでも分かりづらい SQLの学習の [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="995" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">参考書を読んでも分かりづらい</a></li><li class="rtoc-item"><a href="#rtoc-2">結合の種類</a></li><li class="rtoc-item"><a href="#rtoc-3">2テーブルで結合を試していくぅ</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-4">内部結合</a></li><li class="rtoc-item"><a href="#rtoc-5">外部結合(左外部結合、右外部結合)</a></li><li class="rtoc-item"><a href="#rtoc-6">完全外部結合</a></li><li class="rtoc-item"><a href="#rtoc-7">自己結合</a></li><li class="rtoc-item"><a href="#rtoc-8">クロス結合</a></li><li class="rtoc-item"><a href="#rtoc-9">自然結合</a></li><li class="rtoc-item"><a href="#rtoc-10">非等価結合</a></li></ul></li></ol></div><h2 id="rtoc-1" >参考書を読んでも分かりづらい</h2>
<p>SQLの学習のために参考書を読んでも、「クロス結合が〜〜」「自然結合は〜〜」とたくさんの結合名称が出てきてしまい、こんがらがったのでまとめました。</p>
<p>当記事では内部結合と外部結合以外も紹介しているのですが、内部結合と外部結合さえ知っていればやっていけます。</p>
<p>SQL関連の資格を勉強している方やSQLの知識が浅い方は「そういう結合もあるんだ」くらいの理解をして頂ける記事になっていれば幸いです。</p>
<h2 id="rtoc-2" >結合の種類</h2>
<p>自分がテーブル結合の勉強をしている際に出会った結合名称です。</p>
<ol>
<li>内部結合</li>
<li>外部結合(左外部結合、右外部結合)</li>
<li>完全外部結合</li>
<li>自己結合</li>
<li>クロス結合</li>
<li>自然結合</li>
<li>非等価結合</li>
</ol>
<p>※自分はSQLを使用した実務経験が6ヶ月(2022年1月時点)しかないのですが、内部結合と外部結合の使用がほとんどでした。(自己結合と非等価結合は1,2回の使用)</p>
<h2 id="rtoc-3" >2テーブルで結合を試していくぅ</h2>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from testJoin;

	NO NAME       P        AGE T
---------- ---------- - ---------- -
	 1 michel     1 	20 1
	 2 jordan     2 	30 1
	 3
	 4 Lebron     1 	25 1
	 5 hanamiti   2 	18 2
	 0 Popovich   0 	80 2

SQL&gt; select * from testJoin2;

	NO POSITION
---------- ----------
	 1 PG
	 2 SG
	 3 Substitute</code></pre>
<h3 id="rtoc-4" >内部結合</h3>
<p>内部結合は、<span class="sc_marker blue"><strong>結合Keyが一致する行のみを取得するため</strong></span>の構文です。</p>
<p>下記のSQL文は、「No:0」がtestJoin1に登録されていない為、testJoinの「No:0,NAME:Popovich」のデータは取得されません。</p>
<p>マスタデータがないデータを弾く時によく使用されますね。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.name , t2.POSITION from testJoin t1
inner join testJoin2 t2 on t2.NO = t1.pname;   2  

NAME	   POSITION
---------- ----------
michel	   PG
jordan	   SG
Lebron	   PG
hanamiti   SG
</code></pre>
<h3 id="rtoc-5" >外部結合(左外部結合、右外部結合)</h3>
<p>外部結合は、<span class="sc_marker blue"><strong>基となるテーブルのデータをすべて残した上での結合</strong></span>となります。</p>
<p>下記SQL文の場合だと、testJoinを基とするため結合Keyに一致しない「No:0」と「No:3」のレコードを取得することが出来ます。</p>
<pre class="line-numbers"><code class="language-other">select t1.no , t1.name , t2.POSITION from testJoin t1
left join testJoin2 t2 on t2.NO = t1.pname order by t1.no; 
SQL&gt;   2  
	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3
	 4 Lebron     PG
	 5 hanamiti   SG</code></pre>
<h3 id="rtoc-6" >完全外部結合</h3>
<p>完全外部結合は、<strong><span class="sc_marker blue">結合Keyが不一致でも結合するテーブルの全データを取得するため</span></strong>の構文です。</p>
<p>結合Keyに一致しない「No:0,NAME:Popovich」「No:3,NAME:NULL」「No:NULL,NAME:NULL,Position:Substitute」の列が取得されていることが分かります。</p>
<p>正直使ったことないです。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.no , t1.name , t2.POSITION from testJoin t1
Full outer join testJoin2 t2 on t2.NO = t1.pname order by t1.no;   2  

	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3
	 4 Lebron     PG
	 5 hanamiti   SG
		      Substitute</code></pre>
<h3 id="rtoc-7" >自己結合</h3>
<p>自己結合は、<span class="sc_marker blue"><strong>同一のテーブルを別テーブルと考えてデータを取得する</strong></span>ための構文です。</p>
<p>下記SQL文では、同一のチームに所属している選手同士を出力しています。(<span class="sc_marker y">※自己結合は同一テーブルを別テーブルとして扱うので別名称を付与しなければいけません</span>)</p>
<p>余談ですがWHERE句にNAME列の比較演算子を使用しているので、同じ組み合わせのチームを除外しています。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.no,t1.name,t1.team_id,t2.no,t2.name,t2.team_id from testJoin t1 
inner join testJoin t2 on t1.team_id = t2.team_id
where t1.name &gt; t2.name
order by t1.no;   2    3    4  

	NO NAME       T 	NO NAME       T
---------- ---------- - ---------- ---------- -
	 1 michel     1 	 2 jordan     1
	 1 michel     1 	 4 Lebron     1
	 2 jordan     1 	 4 Lebron     1
	 5 hanamiti   2 	 0 Popovich   2</code></pre>
<h3 id="rtoc-8" >クロス結合</h3>
<p>クロス結合は<span class="sc_marker blue">結合するテーブルのデータ数を乗算する</span>構文のことを指します。</p>
<p>testJoinは6個のデータを、testJoin1は3個のデータを保持しています。</p>
<p>そのため6×3=18行が取得されます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select t1.name,t2.POSITION from testJoin t1,testJoin2 t2
  order by t1.no,t2.no;  2  

NAME	   POSITION
---------- ----------
Popovich   PG
Popovich   SG
Popovich   Substitute
michel	   PG
michel	   SG
michel	   Substitute
jordan	   PG
jordan	   SG
jordan	   Substitute
	   PG
	   SG

NAME	   POSITION
---------- ----------
	   Substitute
Lebron	   PG
Lebron	   SG
Lebron	   Substitute
hanamiti   PG
hanamiti   SG
hanamiti   Substitute</code></pre>
<h3 id="rtoc-9" >自然結合</h3>
<p>自然結合は、<span class="sc_marker blue"><strong>結合するテーブル同士のカラム名称とデータ型をSQLさんが判断してくれる</strong></span>構文です。</p>
<p>下記SQL文だと、testJoinのNo列(NUMBER型)とtestJoin1のNo列(NUMBER型)が同一名称、同一データ型になるためNO列を結合Keyに設定してくれています。</p>
<p>下記のデータを正として取得します。</p>
<p>testJoin「No:1,NAME:michel」= testJoin1「No:1,PG」<br />
testJoin「No:2,NAME:jordan」= testJoin1「No:1,SG」<br />
testJoin「No:3,NAME:NULL」= testJoin1「No:1,Substitute」</p>
<p>多分実務で使うこと無いんじゃないかと思います。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select no,t1.name,t2.POSITION from testJoin t1 
natural LEFt join testJoin2 t2;  

	NO NAME       POSITION
---------- ---------- ----------
	 0 Popovich
	 1 michel     PG
	 2 jordan     SG
	 3	      Substitute
	 4 Lebron
	 5 hanamiti
</code></pre>
<h3 id="rtoc-10" >非等価結合</h3>
<p>非等価結合は<span class="sc_marker blue"><strong>結合条件に「＝」演算子を使用しない</strong></span>構文を指します。</p>
<p>「＝」を条件に指定しないだけなので、あまり難しく考える必要はありません。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from testJoin t1 
inner join testJoin2 t2 on t1.PNAME &lt;&gt; t2.POSITION
where t1.no &lt;3
order by t1.no;  2    3    4  

	NO NAME       P        AGE T	     NO POSITION
---------- ---------- - ---------- - ---------- ----------
	 0 Popovich   0 	80 2	      1 PG
	 0 Popovich   0 	80 2	      2 SG
	 0 Popovich   0 	80 2	      3 Substitute
	 1 michel     1 	20 1	      1 PG
	 1 michel     1 	20 1	      2 SG
	 1 michel     1 	20 1	      3 Substitute
	 2 jordan     2 	30 1	      1 PG
	 2 jordan     2 	30 1	      2 SG
	 2 jordan     2 	30 1	      3 Substitute</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/995/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>NULLが嫌いと感じる理由をまとめてみた</title>
		<link>https://otonan-syusyoku.work/archives/945</link>
					<comments>https://otonan-syusyoku.work/archives/945#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 17 Oct 2021 01:14:20 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=945</guid>

					<description><![CDATA[Contents NULLの特徴NULLが嫌い「=」が使えない文字結合ができない値の並び順論理演算にNULLが紛れ込むとやっかい他にもNULLの特徴 NULLとは0でも空文字でもない値のことを指します。（イメージ的には存 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="945" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">NULLの特徴</a></li><li class="rtoc-item"><a href="#rtoc-2">NULLが嫌い</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-3">「=」が使えない</a></li><li class="rtoc-item"><a href="#rtoc-4">文字結合ができない</a></li><li class="rtoc-item"><a href="#rtoc-5">値の並び順</a></li><li class="rtoc-item"><a href="#rtoc-6">論理演算にNULLが紛れ込むとやっかい</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-7">他にも</a></li></ol></div><h2 id="rtoc-1" >NULLの特徴</h2>
<p>NULLとは<span class="sc_marker blue">0でも空文字でもない値</span>のことを指します。（イメージ的には存在しない値を分かりやすくするためにNULLというシールを貼っている状態のこと。）</p>
<p>例えば、財布の中身はいくら？という問いに対して下記の場合が値を保持しているということが証明できます。</p>
<ul>
<li>財布の中身が0円であれば財布が空なので0円という値を保持。</li>
<li>10円が入っていれば10円という値を保持。</li>
</ul>
<p>しかし、財布自体がなければ10円を保持することも0円を保持することもできません。</p>
<p>この財布がない状態の事をSQLの世界ではNULLと呼んでいます。</p>
<h2 id="rtoc-2" >NULLが嫌い</h2>
<h3 id="rtoc-3" >「=」が使えない</h3>
<p>SQLにおいて値の比較や参照において「＝」を使用するのですが、NULLに「＝」は使用できません。</p>
<p>NULLの特徴でもお話したとおり、NULLは値ではないため「＝」「＜」「＞」などの演算子を使用することができません。値ではないものを比較しようとするとSQLさんに怒られます。</p>
<p>そのため、<strong>IS　NULL</strong>という構文を用いて値の参照や比較を行います。</p>
<pre class="line-numbers"><code class="language-other">--名前が無い人の検索
SELECT name FROM family WHERE name IS NULL;

--名前がある人の検索
SELECT name FROM family WHERE name IS NOT NULL;</code></pre>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">補足</div>
<div class="sc_frame ">
<div class="sc_frame_text">NULLに対して「＝」ではなくISを使用していることから<br />
何もない状態を可視化するための目印なので値ではなく、名詞という認識のほうが良いです。</div>
</div>
</div>
<h3 id="rtoc-4" >文字結合ができない</h3>
<p>NULL＋文字列の結合を行なうと異変が起きてしまいます。</p>
<p>MysqlにてNULL値と文字列をCONCAT関数を使用して文字列結合を行うと、NULL値を含む文字列はNULLになってしまいました。(数学で言うところの｛数字×0＝0｝みたいな感じなんですね。)</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; SELECT * FROM BUSYO;
+----------+-----------------+
| busyo_no | busyo_name      |
+----------+-----------------+
|        1 | 開発部          |
|        2 | デザイン部      |
|        3 | 営業部          |
|        4 | サービス部      |
|        5 | NULL            |
+----------+-----------------+
5 rows in set (0.00 sec)

mysql&gt; SELECT CONCAT(busyo_name,'hoge') FROM BUSYO;
+---------------------------+
| CONCAT(busyo_name,'hoge') |
+---------------------------+
| 開発部hoge                |
| デザイン部hoge            |
| 営業部hoge                |
| サービス部hoge            |
| NULL                      |
+---------------------------+
5 rows in set (0.00 sec)</code></pre>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">補足</div>
<div class="sc_frame ">
<div class="sc_frame_text">文字列の結合で特にこんがらがったのが、OracleではNULL値を空文字として扱うという事です。<br />
Oracleにて、CONCAT(&#8216;あいうえお&#8217;,NULL)；を実行すると｛あいうえお’’｝という結果が返ってきます。</div>
</div>
</div>
<h3 id="rtoc-5" >値の並び順</h3>
<p>ORDER BYによって値を並び替える時、NULL値を含む列の場合はNULL値が一番上(もしくは一番下)にきます。</p>
<p><strong>値ではない</strong>のがNULLの特徴なので、<span class="sc_marker blue">比較して並べかえを実現する事はできない</span>みたいです。</p>
<p>&nbsp;</p>
<p>NULL値の順序を指定する場合、「NULLS FIRST(or LAST)」を指定することで思い通りの順序にすることが可能です。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt; select * from fruit2 order by name1;

NAME1	   NAME2
---------- ----------
apple	   orange
apple	   apple
banana	   banana
banana	   apple
banana	   orange
orange	   orange
	           orange

SQL&gt; select * from fruit2 order by name1 nulls first;

NAME1	   NAME2
---------- ----------
	           orange
apple	   orange
apple	   apple
banana	   orange
banana	   banana
banana	   apple
orange	   orange</code></pre>
<h3 id="rtoc-6" >論理演算にNULLが紛れ込むとやっかい</h3>
<p>WHERE句に下記のようなサブクエリを記述した際にサブクエリの結果がNULLを返すと意図しない結果が帰ってきます。</p>
<pre class="line-numbers"><code class="language-other">SQL&gt;SELECT * FROM TEST1
         WHERE no &lt;(SELECT min(no) FROM TEST2);</code></pre>
<p>NULLに比較演算子は使用できないため、サブクエリの結果がNULLになると大元のSQLは１行も返してくれません。</p>
<p>TEST2テーブルにNULLが存在しないと思いこんで上記SQL文を発行してしまうと想定外の結果が帰ってくるので気をつけましょう。</p>
<p>対策としては、サブクエリ内でNULL値を変換してくれるcoalesce関数などの使用がおすすめです。</p>
<h2 id="rtoc-7" >他にも</h2>
<p>まだ学習不足で確認ができていないのですが、</p>
<ul>
<li>インデックスとNULL</li>
<li>NULLの便利な使用方法</li>
</ul>
<p>などを今後追記していきます。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/945/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQLのcase式を理解してしまった</title>
		<link>https://otonan-syusyoku.work/archives/851</link>
					<comments>https://otonan-syusyoku.work/archives/851#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sat, 18 Sep 2021 11:04:58 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=851</guid>

					<description><![CDATA[Contents case式について使用方法SELECT句WHERE句GOURP BY混同しがちなIF文上級者はcase式case式について case式とはSQLで条件分岐するための関数です。 JavaやPHPなどで条件 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame4 preset3 animation-fade rtoc_open noto-sans" data-id="851" data-theme="BlogArise">
			<div id="rtoc-mokuji-title" class=" rtoc_center">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">case式について</a></li><li class="rtoc-item"><a href="#rtoc-2">使用方法</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-3">SELECT句</a></li><li class="rtoc-item"><a href="#rtoc-4">WHERE句</a></li><li class="rtoc-item"><a href="#rtoc-5">GOURP BY</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-6">混同しがちなIF文</a></li><li class="rtoc-item"><a href="#rtoc-7">上級者はcase式</a></li></ol></div><h2 id="rtoc-1" >case式について</h2>
<p>case式とはSQLで条件分岐するための関数です。</p>
<p>JavaやPHPなどで条件分岐する時に使用しているcaseと何ら違いはなく、「〇〇の時はAの処理！」「〇〇はBの処理！」というような指定をすることができます。</p>
<pre class="line-numbers"><code class="language-other">CASE カラム名
　　　WHEN 条件式　THEN "一致した時の値"
   WHEN 条件式 THEN "一致した時の値"
   ELSE "条件のどれとも一致しない時の値"
END</code></pre>
<h2 id="rtoc-2" >使用方法</h2>
<p>case式はSELECT句、WHERE句、ORDER BY句、GROUP BY句など様々な場面で使用できます。</p>
<p>どんな時でも使えるのがケース式です。</p>
<h3 id="rtoc-3" >SELECT句</h3>
<pre class="line-numbers"><code class="language-other">--取得してきたageカラムの値を成人か未成年として表示
SELECT name,
CASE age
　　WHEN age &gt; 19 THEN '成人'
　　WHEN age &lt; 20 THEN ' 未成年'
  ELSE "年齢不詳"
END
FROM SYAIN;</code></pre>
<p>&nbsp;</p>
<h3 id="rtoc-4" >WHERE句</h3>
<pre class="line-numbers"><code class="language-other">--Aのカラムが未来のものだけ取得
SELECT * FROM DUAL
WHERE (CASE WHEN SYSDATE &lt; DATE THEN "未来" END) = A;</code></pre>
<p>&nbsp;</p>
<h3 id="rtoc-5" >GOURP BY</h3>
<pre class="line-numbers"><code class="language-other">SELECT * FROM BUSYO
ORDER BY case busyo_name WHEN busyo_name = "営業" THEN 1
                                                   ELSE 2;</code></pre>
<p>本来の並びであれば｛1:総務部、2:開発部、3:サービス、4:営業｝のところをORDER BY句にケース式を使うことで、営業を一番上に取得することができます。</p>
<h2 id="rtoc-6" >混同しがちなIF文</h2>
<p>PL/SQLなどのSQLを扱うためのプログラミング言語などで使用されるIF文とcase式は混同されがちです。</p>
<p>IF文とcase式はどちらも条件分岐を行なう為の予約後なのですが、名前に文と式の違いがある通り、たくさんの文の中で条件分岐をする為のIF文と一つの文の中で条件分岐をするためのcase式という違いがありまする。</p>
<p>簡単に言うと<span class="sc_marker blue">手続き型言語で使用するのがIF文</span>。<span class="sc_marker blue">非手続き型言語でしようするのがcase式</span>。ということになります。</p>
<p>イメージとしては、SQL文などでSELECT文などを下記のように1回づつ実行していく感じです。<br />
SELECT * FROM DUAL;</p>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame ">
<div class="sc_frame_text">手続き型言語：<br />
大量のプログラムを一度に実行できる言語のこと。<br />
EX)Java、PHP、PL/SQL、非手続き型言語：<br />
一つの命令文を1回づつ実行していく言語のこと。<br />
EX)SQL、C言語</p>
</div>
</div>
</div>
<h2 id="rtoc-7" >上級者はcase式</h2>
<p>「上級者はWHERE句で条件を指定するのではなく、ケース式をSELECT句で使用する」と先輩に言われました。</p>
<p>そのレベルまで行けるようにがんばりまする。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/851/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
