<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>SQL 数据库笔记 - 系列 - 灿若星河 | 郝建锋</title><link>https://philohao.com/series/sql-%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0/</link><description>SQL 数据库笔记 - 系列 - 灿若星河 | 郝建锋</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><managingEditor>haojianfeng1997@gmail.com (Jianfeng.Hao)</managingEditor><webMaster>haojianfeng1997@gmail.com (Jianfeng.Hao)</webMaster><lastBuildDate>Sat, 23 Jan 2021 15:16:59 +0800</lastBuildDate><atom:link href="https://philohao.com/series/sql-%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AC%94%E8%AE%B0/index.xml" rel="self" type="application/rss+xml"/><item><title>数据库笔记 05 - SQL &amp; Pandas 对照学习</title><link>https://philohao.com/2021/01/20210123/</link><pubDate>Sat, 23 Jan 2021 15:16:59 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2021/01/20210123/</guid><description>SQL 与 Pandas 对照学习笔记，整理分组统计、查询和数据处理思路。</description><content:encoded><![CDATA[<p>其实 MySQL 分组统计的实现原理，与 Pandas 几乎是一致的，只要我们理解了 Pandas 分组统计的实现原理，就能理解 MySQL 分组统计的原理。大体过程就是：</p>
<p><img
        class="lazyload"
        data-src="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        data-srcset="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 1.5x, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 2x"
        data-sizes="auto"
        alt="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        title="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8WZPbThsYdogwSV9SoX7nxGGCFXqlbBYtLtia7iaPuxUvZCgIt70DC0aA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
    /></p>
<p><img
        class="lazyload"
        data-src="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        data-srcset="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 1.5x, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 2x"
        data-sizes="auto"
        alt="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        title="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8cmgPcjwI4lxovPHjckjjoJTuetcCibDDY7N4zhdDUCbUtmHH0oFBjmw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
    /></p>
<p>今天我将带大家从 <code>MYSQL</code> 的执行顺序（<strong>FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT</strong>）上，一步步通过 Pandas 向大家展示具体的执行过程，并借助 Python 基础编码，详解更细节的过程。</p>
<h2 id="mysql-分组统计的原理">MySQL 分组统计的原理</h2>
<p>其实上面给的示例代码等价于：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">SELECT
</span></span><span class="line"><span class="cl">  deal_date,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;A区&#39;, order_id, NULL)) &#39;A区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;B区&#39;, order_id, NULL)) &#39;B区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;C区&#39;, order_id, NULL)) &#39;C区&#39;
</span></span><span class="line"><span class="cl">FROM
</span></span><span class="line"><span class="cl">  order_info
</span></span><span class="line"><span class="cl">GROUP BY deal_date;
</span></span></code></pre></td></tr></table>
</div>
</div><p>对于 mysql 标准的执行顺序是：</p>
<blockquote>
<p>FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT</p>
</blockquote>
<p>上面这个 sql 只涉及到 FROM → GROUP BY → SELECT ，可以调整一下 sql 的阅读顺序：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">FROM order_info
</span></span><span class="line"><span class="cl">GROUP BY deal_date
</span></span><span class="line"><span class="cl">SELECT
</span></span><span class="line"><span class="cl">  deal_date,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;A区&#39;, order_id, NULL)) &#39;A区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;B区&#39;, order_id, NULL)) &#39;B区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(area= &#39;C区&#39;, order_id, NULL)) &#39;C区&#39;;
</span></span></code></pre></td></tr></table>
</div>
</div><ol>
<li>FROM</li>
</ol>
<p>首先<code>FROM order_info</code>表示读取 order_info 表的数据</p>
<ol>
<li>GROUP BY</li>
</ol>
<p><code>GROUP BY deal_date</code>表示按照 deal_date 分组</p>
<ol>
<li>SELECT</li>
</ol>
<p>对每个分组选取指定的字段，并根据聚合函数对每个分组结果进行集合</p>
<h2 id="pandas-分组统计的过程">Pandas 分组统计的过程</h2>
<h3 id="from">From</h3>
<p><code>FROM order_info</code>本质就是读取数据：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import pandas as pd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">data = pd.read_csv(&#34;data.csv&#34;, encoding=&#34;gb18030&#34;)
</span></span><span class="line"><span class="cl">data
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<table>
<thead>
<tr>
<th style="text-align:center"></th>
<th style="text-align:center">order_id</th>
<th style="text-align:center">price</th>
<th style="text-align:center">deal_date</th>
<th style="text-align:center">area</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">0</td>
<td style="text-align:center">S001</td>
<td style="text-align:center">10</td>
<td style="text-align:center">2019/1/1</td>
<td style="text-align:center">A 区</td>
</tr>
<tr>
<td style="text-align:center">1</td>
<td style="text-align:center">S002</td>
<td style="text-align:center">20</td>
<td style="text-align:center">2019/1/1</td>
<td style="text-align:center">B 区</td>
</tr>
<tr>
<td style="text-align:center">2</td>
<td style="text-align:center">S003</td>
<td style="text-align:center">30</td>
<td style="text-align:center">2019/1/1</td>
<td style="text-align:center">C 区</td>
</tr>
<tr>
<td style="text-align:center">3</td>
<td style="text-align:center">S004</td>
<td style="text-align:center">40</td>
<td style="text-align:center">2019/1/2</td>
<td style="text-align:center">A 区</td>
</tr>
<tr>
<td style="text-align:center">4</td>
<td style="text-align:center">S005</td>
<td style="text-align:center">10</td>
<td style="text-align:center">2019/1/2</td>
<td style="text-align:center">B 区</td>
</tr>
<tr>
<td style="text-align:center">5</td>
<td style="text-align:center">S006</td>
<td style="text-align:center">20</td>
<td style="text-align:center">2019/1/2</td>
<td style="text-align:center">C 区</td>
</tr>
<tr>
<td style="text-align:center">6</td>
<td style="text-align:center">S007</td>
<td style="text-align:center">30</td>
<td style="text-align:center">2019/1/3</td>
<td style="text-align:center">A 区</td>
</tr>
<tr>
<td style="text-align:center">7</td>
<td style="text-align:center">S008</td>
<td style="text-align:center">40</td>
<td style="text-align:center">2019/1/3</td>
<td style="text-align:center">C 区</td>
</tr>
</tbody>
</table>
<p>对于 Mysql 的任何 InnoDB 引擎表来说都存在一个主键索引，在没有指定任何字段作为主键时，InnoDB 表会生成一个 6 字节空间的自增主键 row_id 作为主键。上面的 Pandas 表的 Index(<code>data.index</code>)就相当于 mysql 表的自增主键 row_id。</p>
<p>当然这张 MySQL 表指定 order_id 为主键时：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ALTER TABLE order_info ADD PRIMARY KEY (order_id);
</span></span></code></pre></td></tr></table>
</div>
</div><p>就相当于：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">data.set_index(&#34;order_id&#34;)
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<p><img
        class="lazyload"
        data-src="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8IPXHG6u09oiaxiclQf5Bnw7PPh21qmHEUhf2qhlXYj1MtxFdeX2AsYXQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        data-srcset="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8IPXHG6u09oiaxiclQf5Bnw7PPh21qmHEUhf2qhlXYj1MtxFdeX2AsYXQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8IPXHG6u09oiaxiclQf5Bnw7PPh21qmHEUhf2qhlXYj1MtxFdeX2AsYXQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 1.5x, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8IPXHG6u09oiaxiclQf5Bnw7PPh21qmHEUhf2qhlXYj1MtxFdeX2AsYXQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 2x"
        data-sizes="auto"
        alt="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8IPXHG6u09oiaxiclQf5Bnw7PPh21qmHEUhf2qhlXYj1MtxFdeX2AsYXQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        title="图片"
    /></p>
<h3 id="group-by">GROUP BY</h3>
<p><code>GROUP BY deal_date</code>表示按照 deal_date 分组，即：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">df_group = data.groupby(&#34;deal_date&#34;)
</span></span><span class="line"><span class="cl">df_group
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&lt;pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000000016CE8278&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>其实这步的本质是获取每个分组对应的主键 id 列表，可以通过<code>DataFrameGroupBy</code>对象的<code>groups</code>方法查看：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">df_group.groups
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;2019/1/1&#39;: [0, 1, 2], &#39;2019/1/2&#39;: [3, 4, 5], &#39;2019/1/3&#39;: [6, 7]}
</span></span></code></pre></td></tr></table>
</div>
</div><p>Pandas 返回的是每个分组对应的索引列表，它等价于 MySQL 的主键 id 列表。</p>
<h3 id="select">SELECT</h3>
<p>我们拿到每个分组对应的索引列表后，就可以拿到每个分组对应的全部数据：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">for deal_date, ids in df_group.groups.items():
</span></span><span class="line"><span class="cl">    print(deal_date)
</span></span><span class="line"><span class="cl">    display(data.loc[ids])
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<p><img
        class="lazyload"
        data-src="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8xCzx6goic3G7vdOntZYBVPBmsE5MSiaxice8Yic9jQ33IoJU43u0WFInTA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        data-srcset="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8xCzx6goic3G7vdOntZYBVPBmsE5MSiaxice8Yic9jQ33IoJU43u0WFInTA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8xCzx6goic3G7vdOntZYBVPBmsE5MSiaxice8Yic9jQ33IoJU43u0WFInTA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 1.5x, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8xCzx6goic3G7vdOntZYBVPBmsE5MSiaxice8Yic9jQ33IoJU43u0WFInTA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 2x"
        data-sizes="auto"
        alt="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8xCzx6goic3G7vdOntZYBVPBmsE5MSiaxice8Yic9jQ33IoJU43u0WFInTA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        title="图片"
    /></p>
<p>当然，由于 Pandas 本身有现成的 API，我们实际并不会这样遍历每个分区，而是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">for deal_date, split in df_group:
</span></span><span class="line"><span class="cl">    print(deal_date)
</span></span><span class="line"><span class="cl">    display(split)
</span></span></code></pre></td></tr></table>
</div>
</div><p>这段 Pandas 遍历每个分区的本质就是上面的代码，返回结果也与上面完全相同。</p>
<p>对于 MySQL 的 select 这步：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">SELECT
</span></span><span class="line"><span class="cl">  deal_date,
</span></span><span class="line"><span class="cl">  COUNT(IF(AREA= &#39;A区&#39;, 1, NULL)) &#39;A区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(AREA= &#39;B区&#39;, 1, NULL)) &#39;B区&#39;,
</span></span><span class="line"><span class="cl">  COUNT(IF(AREA= &#39;C区&#39;, 1, NULL)) &#39;C区&#39;
</span></span></code></pre></td></tr></table>
</div>
</div><p>由于前面分组的存在，<code>count()</code>聚合函数将作用于每一个分组，用 Pandas 表达就是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">for deal_date, split in df_group:
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;A区&#39;, &#39;A区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;B区&#39;, &#39;B区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;C区&#39;, &#39;C区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split = split.set_index(&#39;deal_date&#39;)
</span></span><span class="line"><span class="cl">    split = split[[&#39;A区&#39;, &#39;B区&#39;, &#39;C区&#39;]]
</span></span><span class="line"><span class="cl">    display(split)
</span></span><span class="line"><span class="cl">    display(split.count().to_frame(deal_date).T)
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<p><img
        class="lazyload"
        data-src="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8d5OLZYIWhZbSNFpOGk9oib0nvx0tCmm365ddanTpGelTD3TbbVA5PGA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        data-srcset="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8d5OLZYIWhZbSNFpOGk9oib0nvx0tCmm365ddanTpGelTD3TbbVA5PGA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8d5OLZYIWhZbSNFpOGk9oib0nvx0tCmm365ddanTpGelTD3TbbVA5PGA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 1.5x, https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8d5OLZYIWhZbSNFpOGk9oib0nvx0tCmm365ddanTpGelTD3TbbVA5PGA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1 2x"
        data-sizes="auto"
        alt="https://mmbiz.qpic.cn/mmbiz_png/tXYict40xfLh0Ik9K1kXOEAmHWbyyibhT8d5OLZYIWhZbSNFpOGk9oib0nvx0tCmm365ddanTpGelTD3TbbVA5PGA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1"
        title="图片"
    /></p>
<h3 id="return">Return</h3>
<p>最后 MySQL 计算完成后，就会合并每个分组的结果集，用 Pandas 表达就是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">result = []
</span></span><span class="line"><span class="cl">for deal_date, split in df_group:
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;A区&#39;, &#39;A区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;B区&#39;, &#39;B区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;C区&#39;, &#39;C区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split = split.set_index(&#39;deal_date&#39;)
</span></span><span class="line"><span class="cl">    split = split[[&#39;A区&#39;, &#39;B区&#39;, &#39;C区&#39;]]
</span></span><span class="line"><span class="cl">    result.append(split.count().to_frame(deal_date).T)
</span></span><span class="line"><span class="cl">result = pd.concat(result)
</span></span><span class="line"><span class="cl">result
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<table>
<thead>
<tr>
<th style="text-align:center"></th>
<th style="text-align:center">A 区</th>
<th style="text-align:center">B 区</th>
<th style="text-align:center">C 区</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">2019/1/1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
</tr>
<tr>
<td style="text-align:center">2019/1/2</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
</tr>
<tr>
<td style="text-align:center">2019/1/3</td>
<td style="text-align:center">1</td>
<td style="text-align:center">0</td>
<td style="text-align:center">1</td>
</tr>
</tbody>
</table>
<h2 id="pandas-分组聚合的执行过程">Pandas 分组聚合的执行过程</h2>
<p>对于上面完整 MySQL 语句，整体执行流程等价于 Pandas 的：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">def group_func(split):
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;A区&#39;, &#39;A区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;B区&#39;, &#39;B区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split.loc[split.area == &#39;C区&#39;, &#39;C区&#39;] = split.order_id
</span></span><span class="line"><span class="cl">    split = split[[&#39;A区&#39;, &#39;B区&#39;, &#39;C区&#39;]]
</span></span><span class="line"><span class="cl">    return split.count()
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">data.groupby(&#39;deal_date&#39;, as_index=False).apply(group_func)
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="python-演示分组的具体原理">Python 演示分组的具体原理</h2>
<p>上面的演示中：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">data.groupby(&#34;deal_date&#34;).groups
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;2019/1/1&#39;: [0, 1, 2], &#39;2019/1/2&#39;: [3, 4, 5], &#39;2019/1/3&#39;: [6, 7]}
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到 Pandas 和 MySQL 分组这步其实都是计算出了每个分组对应的主键 id（索引 id）。但它们具体又是怎么实现的呢？</p>
<p>这时候，我用纯 python 来给大家演示一下。</p>
<p>不管是 MySQL 还是 Pandas，都带有主键索引，只不过 Pandas 的索引不会因为重复而报错，而 MySQL 的索引是肯定唯一的，会覆盖前面索引相同的数据。</p>
<p>虽然 MySQL 将带有索引的数据存储到了磁盘上面，但为了方便，我只在内存上演示索引构建的过程。另外 MySQL 主键索引的数据结构一般是 B+树，这里我用 hash 表（字典）来简单演示。</p>
<p>首先，读取数据并构建索引：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">import</span> <span class="n">csv</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="n">columns</span> <span class="o">=</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl"><span class="n">with</span> <span class="n">open</span><span class="p">(</span><span class="s2">&#34;data.csv&#34;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&#34;gb18030&#34;</span><span class="p">)</span> <span class="n">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">f_csv</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">reader</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">columns</span> <span class="o">=</span> <span class="n">next</span><span class="p">(</span><span class="n">f_csv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">columns</span> <span class="o">=</span> <span class="n">dict</span><span class="p">(</span><span class="n">zip</span><span class="p">(</span><span class="n">columns</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="n">len</span><span class="p">(</span><span class="n">columns</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">enumerate</span><span class="p">(</span><span class="n">f_csv</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">display</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;order_id&#39;: 0, &#39;price&#39;: 1, &#39;deal_date&#39;: 2, &#39;area&#39;: 3}
</span></span><span class="line"><span class="cl">{0: [&#39;S001&#39;, &#39;10&#39;, &#39;2019/1/1&#39;, &#39;A区&#39;],
</span></span><span class="line"><span class="cl"> 1: [&#39;S002&#39;, &#39;20&#39;, &#39;2019/1/1&#39;, &#39;B区&#39;],
</span></span><span class="line"><span class="cl"> 2: [&#39;S003&#39;, &#39;30&#39;, &#39;2019/1/1&#39;, &#39;C区&#39;],
</span></span><span class="line"><span class="cl"> 3: [&#39;S004&#39;, &#39;40&#39;, &#39;2019/1/2&#39;, &#39;A区&#39;],
</span></span><span class="line"><span class="cl"> 4: [&#39;S005&#39;, &#39;10&#39;, &#39;2019/1/2&#39;, &#39;B区&#39;],
</span></span><span class="line"><span class="cl"> 5: [&#39;S006&#39;, &#39;20&#39;, &#39;2019/1/2&#39;, &#39;C区&#39;],
</span></span><span class="line"><span class="cl"> 6: [&#39;S007&#39;, &#39;30&#39;, &#39;2019/1/3&#39;, &#39;A区&#39;],
</span></span><span class="line"><span class="cl"> 7: [&#39;S008&#39;, &#39;40&#39;, &#39;2019/1/3&#39;, &#39;C区&#39;]}
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样我们就读取数据并构建了主键索引，以及表的列名元信息。</p>
<p>下面我们开始实现分组：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># 获取分组数据所在的列
</span></span><span class="line"><span class="cl">group_num = columns[&#39;deal_date&#39;]
</span></span><span class="line"><span class="cl">id_groups = {}
</span></span><span class="line"><span class="cl">for index, row in data.items():
</span></span><span class="line"><span class="cl">    group_key = row[group_num]
</span></span><span class="line"><span class="cl">    ids = id_groups.setdefault(group_key, [])
</span></span><span class="line"><span class="cl">    ids.append(index)
</span></span><span class="line"><span class="cl">id_groups
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;2019/1/1&#39;: [0, 1, 2], &#39;2019/1/2&#39;: [3, 4, 5], &#39;2019/1/3&#39;: [6, 7]}
</span></span></code></pre></td></tr></table>
</div>
</div><p>最后完成聚合计算：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">result = {}
</span></span><span class="line"><span class="cl">for deal_date, ids in id_groups.items():
</span></span><span class="line"><span class="cl">    areas = result.setdefault(deal_date, [0, 0, 0])
</span></span><span class="line"><span class="cl">    for index in ids:
</span></span><span class="line"><span class="cl">        area = data[index][columns[&#39;area&#39;]]
</span></span><span class="line"><span class="cl">        if area == &#39;A区&#39;:
</span></span><span class="line"><span class="cl">            areas[0] += 1
</span></span><span class="line"><span class="cl">        elif area == &#39;B区&#39;:
</span></span><span class="line"><span class="cl">            areas[1] += 1
</span></span><span class="line"><span class="cl">        elif area == &#39;C区&#39;:
</span></span><span class="line"><span class="cl">            areas[2] += 1
</span></span><span class="line"><span class="cl">result
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{&#39;2019/1/1&#39;: [1, 1, 1], &#39;2019/1/2&#39;: [1, 1, 1], &#39;2019/1/3&#39;: [1, 0, 1]}
</span></span></code></pre></td></tr></table>
</div>
</div><p>借助 Pandas 展示一下最终结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">pd.DataFrame.from_dict(result, &#39;index&#39;, columns=[&#34;A区&#34;, &#34;B区&#34;, &#34;C区&#34;])
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded></item><item><title>数据库笔记 04 - Python 操控指南</title><link>https://philohao.com/2020/12/20201202/</link><pubDate>Wed, 02 Dec 2020 15:19:59 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2020/12/20201202/</guid><description>Python 操作数据库学习笔记，概览连接、查询和数据交互的基础方法。</description><content:encoded><![CDATA[<p>这两天待在家里比较闲，利用网络资源学了点儿数据库相关知识，同时对如何用 Python 与数据库进行交互有了进一步的了解。在这里主要是概览性的记录一下学习到的知识点，以备日后温习之用。</p>
<h2 id="key-1-sql-和-nosql">Key 1. SQL 和 NoSQL</h2>
<h3 id="sql">SQL</h3>
<p>SQL 是一种  <strong>结构性查询语言</strong>，用于在关系数据库管理系统（RDBMS）中检索和管理数据。</p>
<p>关系型数据库侧重于以二维表格的形式组织数据。 在实际的关系数据库中的关系也称表，一个关系数据库就是由若干个表组成，每个关系表是一个如下形式的二维数组：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">+----+----------+-----+-----------+----------+
</span></span><span class="line"><span class="cl">| ID | NAME     | AGE | ADDRESS   | SALARY   |
</span></span><span class="line"><span class="cl">+----+----------+-----+-----------+----------+
</span></span><span class="line"><span class="cl">|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
</span></span><span class="line"><span class="cl">|  2 | Khilan   |  25 | Delhi     |  1500.00 |
</span></span><span class="line"><span class="cl">|  3 | kaushik  |  23 | Kota      |  2000.00 |
</span></span><span class="line"><span class="cl">|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
</span></span><span class="line"><span class="cl">|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
</span></span><span class="line"><span class="cl">|  6 | Komal    |  22 | MP        |  4500.00 |
</span></span><span class="line"><span class="cl">|  7 | Muffy    |  24 | Indore    | 10000.00 |
</span></span><span class="line"><span class="cl">+----+----------+-----+-----------+----------+
</span></span></code></pre></td></tr></table>
</div>
</div><p>常见的以 SQL 作为标准数据库语言的关系型数据库有：<a href="https://www.mysql.com/" target="_blank" rel="noopener noreffer">MySQL</a>、<a href="https://www.postgresql.org/" target="_blank" rel="noopener noreffer">PostgreSQL</a>、<a href="https://www-01.ibm.com/software/data/db2/" target="_blank" rel="noopener noreffer">DB2</a>、<a href="https://www.microsoft.com/en-us/sqlserver/default.aspx" target="_blank" rel="noopener noreffer">SQL Server</a> 等。有关 SQL 语句的教程网上有很多，有兴趣的可以看看 <a href="https://www.runoob.com/sql/sql-tutorial.html" target="_blank" rel="noopener noreffer">SQL 教程</a>，比较全面。</p>
<h3 id="nosql">Nosql</h3>
<p>Nosql (Not Only SQL) 指一系列旨在实现数据库模型的方法和项目，与传统的通过 SQL 访问数据的关系型数据库有很大的不同。 使用 NoSQL 的情况下，现实中实体之间的复杂关系可以通过使用不同的数据结构来存储，如：哈希表、数组、树等。</p>
<p>这两天主要学习了 MongoDB 和 Redis 的基本语法及其 Python 实现，有关语法可以参考 <a href="https://www.runoob.com/mongodb/mongodb-tutorial.html" target="_blank" rel="noopener noreffer">MongoDB 教程</a> 和 <a href="https://www.runoob.com/redis/redis-tutorial.html" target="_blank" rel="noopener noreffer">Redis 教程</a>。</p>
<h3 id="总结---中文教程">总结 - 中文教程</h3>
<ul>
<li><a href="https://www.runoob.com/sql/sql-tutorial.html" target="_blank" rel="noopener noreffer">SQL</a></li>
<li><a href="https://www.runoob.com/mongodb/mongodb-tutorial.html" target="_blank" rel="noopener noreffer">MongoDB</a></li>
<li><a href="https://www.runoob.com/redis/redis-tutorial.html" target="_blank" rel="noopener noreffer">Redis</a></li>
</ul>
<h2 id="key-2-python-操作数据库">Key 2. Python 操作数据库</h2>
<p>使用 Python 操作数据库主要有两种方式，以 MySQL 为例：</p>
<ol>
<li>使用原生模块：<code>pymysql</code></li>
<li>ORM 框架：<code>SQLAchemy</code></li>
</ol>
<p>SQLAlchemy 是 python 编程语言下的一款 ORM 框架，面向对象编程把所有实体看成对象（object），关系型数据库则是采用实体之间的关系（relation）连接数据。很早就有人提出，关系也可以用对象表达，这样的话，就能使用面向对象编程，来操作关系型数据库。</p>
<p>简单说，ORM 就是通过实例对象的语法，完成关系型数据库的操作的技术，是&quot;对象-关系映射&quot;（Object/Relational Mapping） 的缩写，ORM 把数据库映射成对象：</p>
<ul>
<li>数据库的表（table） &ndash;&gt; 类（class）</li>
<li>记录（record，行数据）&ndash;&gt; 对象（object）</li>
<li>字段（field）&ndash;&gt; 对象的属性（attribute）</li>
</ul>
]]></content:encoded></item><item><title>数据库笔记 03 - 窗口函数篇</title><link>https://philohao.com/2020/12/20201201/</link><pubDate>Tue, 01 Dec 2020 13:37:44 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2020/12/20201201/</guid><description>SQL 窗口函数学习笔记，整理 OVER、分区、排序和常见分析函数。</description><content:encoded><![CDATA[<h2 id="窗口函数的基本用法">窗口函数的基本用法</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="err">函数名</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="p">()</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">xx</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p>窗口函数就是将表以窗口为单位进行分割，并在其中进行<strong>分组排序</strong>的函数。</p>
</li>
<li>
<p><code>OVER</code> 关键字用来指定函数执行的窗口范围，若后面括号中什么都不写，则意味着窗口包含满足 <code>WHERE</code> 条件的所有行，窗口函数基于所有行进行计算；如果不为空，则支持以下 4 种语法来设置窗口。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="n">mysql</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">rk</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">PERCENT_RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">prk</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">WINDOW</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">score</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p><code>window_name</code>：给窗口指定一个别名。如果 SQL 中涉及的窗口较多，采用别名可以看起来更清晰易读</p>
</li>
<li>
<p><code>partition by</code> 子句：窗口按照哪些字段进行分组，窗口函数在不同的分组上分别执行</p>
</li>
<li>
<p><code>order by</code> 子句：按照哪些字段进行排序，窗口函数将按照排序后的记录顺序进行编号</p>
</li>
<li>
<p><code>frame</code> 子句：frame 是当前分区的一个子集，子句用来定义子集的规则，通常用来作为滑动窗口使用，这样的统计方法称为<strong>移动平均</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--指定“最靠近的3行”作为汇总对象
</span></span></span><span class="line"><span class="cl"><span class="c1">--使用 ROWS（行）和 PRECEDING(之前)两个关键字，将框架指定为“截止到之前~行”
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">SELECT</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_id</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_name</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">sale_price</span><span class="p">,</span><span class="w">        
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">sale_price</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">product_id</span><span class="w"> </span><span class="k">ROWS</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">PRECEDING</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">moving_avg</span><span class="w">   
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Product</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>使用关键字 FOLLOWING(之后)替换 PRECEDING，就可以指定“截止到之后~行”作为框架。如果希望将当前记录的前后行作为汇总对象，可以同时使用 PRECEDING(之前)和 FOLLOWING（之后）关键字来实现。</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--将当前记录的前后行作为汇总对象
</span></span></span><span class="line"><span class="cl"><span class="c1">--当前记录的前后行的具体含义就是：之前1行的记录 + 自身（当前记录）+ 之后1行的记录
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">SELECT</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_id</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_name</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">sale_price</span><span class="p">,</span><span class="w">       
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">sale_price</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">product_id</span><span class="w"> </span><span class="k">ROWS</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">PRECEDING</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">FOLLOWING</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">moving_avg</span><span class="w">   
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Product</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
</ul>
<h2 id="窗口函数的执行顺序">窗口函数的执行顺序</h2>
<blockquote>
<p><strong>原理</strong>：窗口函数的执行顺序（逻辑上的）是在 FROM, JOIN, WHERE, GROUP BY, HAVING 之后，在 ORDER BY, LIMIT, SELECT DISTINCT 之前。它执行时 GROUP BY 的聚合过程已经完成了，所以不会再产生数据聚合。</p>
</blockquote>
<p>注：窗口函数是在 where 之后执行的，所以如果 where 子句需要用窗口函数作为条件，需要多一层查询，在子查询外面进行</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">select</span><span class="w"> </span><span class="n">user_id</span><span class="p">,</span><span class="w"> </span><span class="k">avg</span><span class="p">(</span><span class="n">diff</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">from</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">select</span><span class="w"> </span><span class="n">user_id</span><span class="p">,</span><span class="w"> </span><span class="n">lead</span><span class="p">(</span><span class="n">log_time</span><span class="p">)</span><span class="w"> </span><span class="n">over</span><span class="p">(</span><span class="n">partition</span><span class="w"> </span><span class="n">user_id</span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">log_time</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">log_time</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">diff</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">from</span><span class="w"> </span><span class="n">user_log</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w"> </span><span class="n">datediff</span><span class="p">(</span><span class="n">now</span><span class="p">(),</span><span class="w"> </span><span class="n">t</span><span class="p">.</span><span class="n">log_time</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">group</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">user_id</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="窗口函数和普通聚合函数的区别">窗口函数和普通聚合函数的区别</h2>
<ol>
<li>
<p>聚合函数是将多条记录聚合为一条；窗口函数是每条记录都会执行，有几条记录执行完还是几条</p>
</li>
<li>
<p>所有的聚合函数都能用作窗口函数，起到类似<strong>累加/累乘</strong>的效果</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--将SUM函数作为窗口函数使用
</span></span></span><span class="line"><span class="cl"><span class="c1">--使用聚合函数作为窗口函数时，需要在其括号内指定相应的列
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">SELECT</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_id</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">product_name</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">sale_price</span><span class="p">,</span><span class="w">        
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SUM</span><span class="p">(</span><span class="n">sale_price</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">product_id</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">current_sum</span><span class="w">   
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Product</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>目前为止我们学过的函数大多数都没有使用位置的限制，最多也就是<u>在 WHERE 子句不能使用聚合函数</u>。但是，使用窗口函数的位置却有很大的限制，确切的说，<u>窗口函数只能在 SELECT 子句中使用</u>。</p>
</li>
</ol>
<h2 id="常用窗口函数">常用窗口函数</h2>
<h3 id="序号函数">序号函数</h3>
<blockquote>
<p>row_number(), rank(), dense_rank()</p>
<p>应用场景：【排名问题】 - 如，各科的第一名分别是谁？</p>
</blockquote>
<ul>
<li>
<p><code>ROW_NUMBER()</code>：顺序排序——1、2、3</p>
</li>
<li>
<p><code>RANK()</code>：并列排序，跳过重复序号——1、1、3</p>
</li>
<li>
<p><code>DENSE_RANK()</code>：并列排序，不跳过重复序号——1、1、2</p>
</li>
</ul>
<h3 id="分布函数">分布函数</h3>
<blockquote>
<p>percent_rank(), cume_dist()</p>
<p>应用场景：【比例问题】 - 如，小于等于当前成绩的比例？</p>
</blockquote>
<ul>
<li>
<p>percent_rank()：每行按照公式<code>(rank-1) / (rows-1)</code>进行计算。其中，<code>rank</code>为<code>RANK()函数</code>产生的序号，<code>rows</code>为当前窗口的记录总行数</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--给窗口指定别名：WINDOW w AS (PARTITION BY stu_id ORDER BY score)
</span></span></span><span class="line"><span class="cl"><span class="c1">--此例中 rows = 7
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">mysql</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">rk</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">PERCENT_RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">prk</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">WINDOW</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">score</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">----+------+--------+-----------+-------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w"> </span><span class="n">rk</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">prk</span><span class="w">  </span><span class="o">|</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">score</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">----+------+--------+-----------+-------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w">  </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">0</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L003</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">79</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w">  </span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L004</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">75</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L005</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">75</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">0</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L006</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">82</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">  </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L007</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">----+------+--------+-----------+-------+
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>cume_dist()：分组内小于、等于当前 rank 值的行数 / 分组内总行数 eg:查询小于等于当前成绩（score）的比例</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--cd1：没有分区，则所有数据均为一组，总行数为 8
</span></span></span><span class="line"><span class="cl"><span class="c1">--cd2：按照 lesson_id 分成了两组，行数各为 4
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">mysql</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">CUME_DIST</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">score</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">cd1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">CUME_DIST</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">score</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">cd2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;L001&#39;</span><span class="p">,</span><span class="s1">&#39;L002&#39;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------+------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">score</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">cd1</span><span class="w">   </span><span class="o">|</span><span class="w"> </span><span class="n">cd2</span><span class="w">  </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------+------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">84</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">125</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">  </span><span class="mi">0</span><span class="p">.</span><span class="mi">75</span><span class="w"> </span><span class="o">|</span><span class="w">  </span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">875</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">75</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">   </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">     </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w">  </span><span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">375</span><span class="w"> </span><span class="o">|</span><span class="w">  </span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">90</span><span class="w"> </span><span class="o">|</span><span class="w">   </span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">75</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">625</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------+------+
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="前后函数">前后函数</h3>
<blockquote>
<p>lag(expr, n), lead(expr, n)</p>
<p>作用：返回位于当前行的前 n 行（<code>LAG(expr,n)</code>）或后 n 行（<code>LEAD(expr,n)</code>）的 expr 的值</p>
<p>应用场景：查询前 1 名同学的成绩和当前同学成绩的差值</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="n">mysql</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="p">,</span><span class="w"> </span><span class="n">pre_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">score</span><span class="o">-</span><span class="n">pre_score</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">diff</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">FROM</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w">     </span><span class="k">SELECT</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w">     </span><span class="n">LAG</span><span class="p">(</span><span class="n">score</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">pre_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w">     </span><span class="k">FROM</span><span class="w"> </span><span class="n">t_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w">     </span><span class="k">WHERE</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;L001&#39;</span><span class="p">,</span><span class="s1">&#39;L002&#39;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w">     </span><span class="n">WINDOW</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">score</span><span class="p">))</span><span class="w"> </span><span class="n">t</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-----------+------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">score</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">pre_score</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">diff</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-----------+------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">84</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="k">NULL</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">84</span><span class="w"> </span><span class="o">|</span><span class="w">   </span><span class="mi">14</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">   </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w">      </span><span class="k">NULL</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">90</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">90</span><span class="w"> </span><span class="o">|</span><span class="w">    </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-----------+------+
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="头尾函数">头尾函数</h3>
<blockquote>
<p>FIRST_VALUE(expr), LAST_VALUE(expr)</p>
<p>作用：返回第一个（<code>FIRST_VALUE(expr)</code>）或最后一个（<code>LAST_VALUE(expr)</code>）expr 的值</p>
<p>应用场景：截止到当前成绩，按照日期排序查询第 1 个和最后 1 个同学的分数</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="n">mysql</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">stu_id</span><span class="p">,</span><span class="w"> </span><span class="n">lesson_id</span><span class="p">,</span><span class="w"> </span><span class="n">score</span><span class="p">,</span><span class="w"> </span><span class="n">create_time</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">FIRST_VALUE</span><span class="p">(</span><span class="n">score</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">first_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">LAST_VALUE</span><span class="p">(</span><span class="n">score</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">last_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">t_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;L001&#39;</span><span class="p">,</span><span class="s1">&#39;L002&#39;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">WINDOW</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">create_time</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------------+-------------+------------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w"> </span><span class="n">stu_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">lesson_id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">score</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">create_time</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">first_score</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">last_score</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------------+-------------+------------+
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">   </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">07</span><span class="w">  </span><span class="o">|</span><span class="w">         </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">        </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">08</span><span class="w">  </span><span class="o">|</span><span class="w">         </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">98</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">84</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">09</span><span class="w">  </span><span class="o">|</span><span class="w">         </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L001</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">09</span><span class="w">  </span><span class="o">|</span><span class="w">         </span><span class="mi">100</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">99</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">3</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">07</span><span class="w">  </span><span class="o">|</span><span class="w">          </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">1</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">08</span><span class="w">  </span><span class="o">|</span><span class="w">          </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">86</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">2</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">90</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">09</span><span class="w">  </span><span class="o">|</span><span class="w">          </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">90</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">|</span><span class="w">      </span><span class="mi">4</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">L002</span><span class="w">      </span><span class="o">|</span><span class="w">    </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">2018</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">10</span><span class="w">  </span><span class="o">|</span><span class="w">          </span><span class="mi">91</span><span class="w"> </span><span class="o">|</span><span class="w">         </span><span class="mi">88</span><span class="w"> </span><span class="o">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">+</span><span class="c1">--------+-----------+-------+-------------+-------------+------------+
</span></span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded></item><item><title>数据库笔记 02 - MySQL 函数</title><link>https://philohao.com/2020/02/20200218/</link><pubDate>Tue, 18 Feb 2020 23:46:13 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2020/02/20200218/</guid><description>MySQL 函数学习笔记，整理空值处理、字符串、日期和聚合函数用法。</description><content:encoded><![CDATA[<h2 id="mysql-常用函数">MySQL 常用函数</h2>
<h3 id="null-函数">NULL 函数</h3>
<p>ISNULL()、NVL()、IFNULL() 和 COALESCE() 函数</p>
<h3 id="日期函数">日期函数</h3>
<p>MySQL 使用下列数据类型在数据库中存储日期或日期/时间值：</p>
<ul>
<li>DATE - 格式：YYYY-MM-DD</li>
<li>DATETIME - 格式：YYYY-MM-DD HH:MM:SS</li>
<li>TIMESTAMP - 格式：YYYY-MM-DD HH:MM:SS</li>
<li>YEAR - 格式：YYYY 或 YY</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align:left">函数</th>
<th style="text-align:left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-now.html" target="_blank" rel="noopener noreffer">NOW()</a></td>
<td style="text-align:left">返回当前的日期和时间</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-curdate.html" target="_blank" rel="noopener noreffer">CURDATE()</a></td>
<td style="text-align:left">返回当前的日期</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-curtime.html" target="_blank" rel="noopener noreffer">CURTIME()</a></td>
<td style="text-align:left">返回当前的时间</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-date.html" target="_blank" rel="noopener noreffer">DATE()</a></td>
<td style="text-align:left">提取日期或日期/时间表达式的日期部分</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-extract.html" target="_blank" rel="noopener noreffer">EXTRACT()</a></td>
<td style="text-align:left">返回日期/时间的单独部分</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-date-add.html" target="_blank" rel="noopener noreffer">DATE_ADD()</a></td>
<td style="text-align:left">向日期添加指定的时间间隔</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-date-sub.html" target="_blank" rel="noopener noreffer">DATE_SUB()</a></td>
<td style="text-align:left">从日期减去指定的时间间隔</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-datediff-mysql.html" target="_blank" rel="noopener noreffer">DATEDIFF()</a></td>
<td style="text-align:left">返回两个日期之间的天数</td>
</tr>
<tr>
<td style="text-align:left"><a href="https://www.runoob.com/sql/func-date-format.html" target="_blank" rel="noopener noreffer">DATE_FORMAT()</a></td>
<td style="text-align:left">用不同的格式显示日期/时间</td>
</tr>
</tbody>
</table>
<h3 id="aggregate-函数">Aggregate 函数</h3>
<p>SQL Aggregate 函数计算从列中取得的值，返回一个单一的值。</p>
<table>
<thead>
<tr>
<th>函数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>AVG()</td>
<td>返回平均值</td>
</tr>
<tr>
<td>COUNT()</td>
<td>返回行数</td>
</tr>
<tr>
<td>FIRST()</td>
<td>返回第一个记录的值</td>
</tr>
<tr>
<td>LAST()</td>
<td>返回最后一个记录的值</td>
</tr>
<tr>
<td>MAX()</td>
<td>返回最大值</td>
</tr>
<tr>
<td>MIN()</td>
<td>返回最小值</td>
</tr>
<tr>
<td>SUM()</td>
<td>返回总和</td>
</tr>
</tbody>
</table>
<h3 id="scalar-函数">Scalar 函数</h3>
<p>SQL Scalar 函数基于输入值，返回一个单一的值。</p>
<table>
<thead>
<tr>
<th>函数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>UCASE()</td>
<td>将某个字段转换为大写</td>
</tr>
<tr>
<td>LCASE()</td>
<td>将某个字段转换为小写</td>
</tr>
<tr>
<td>MID()</td>
<td>从某个文本字段提取字符，MySql 中使用</td>
</tr>
<tr>
<td>SubString(字段，1，end)</td>
<td>从某个文本字段提取字符</td>
</tr>
<tr>
<td>LEN()</td>
<td>返回某个文本字段的长度</td>
</tr>
<tr>
<td>ROUND()</td>
<td>对某个数值字段进行指定小数位数的四舍五入</td>
</tr>
<tr>
<td>NOW()</td>
<td>返回当前的系统日期和时间</td>
</tr>
<tr>
<td>FORMAT()</td>
<td>格式化某个字段的显示方式</td>
</tr>
</tbody>
</table>
<p>有关上述函数的具体使用，可以参考：<a href="https://www.runoob.com/sql/sql-function.html" target="_blank" rel="noopener noreffer">https://www.runoob.com/sql/sql-function.html</a></p>
]]></content:encoded></item><item><title>数据库笔记 01 - SQL 语法篇</title><link>https://philohao.com/2020/02/20200217/</link><pubDate>Mon, 17 Feb 2020 22:28:47 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2020/02/20200217/</guid><description>SQL 语法学习笔记，概览关系型数据库常用操作和语句分类。</description><content:encoded><![CDATA[<p>SQL（Structured Query Language）是「结构化查询语言」，它是对关系型数据库的操作语言。它可以应用到所有关系型数据库中，例如：MySQL、Oracle、SQL Server 等。它主要划分为以下几类：</p>
<ul>
<li><strong>DQL - Data Query Language</strong>：数据查询语言，用来查询记录（数据）。<u>select</u></li>
<li><strong>DDL - Data Definition Language</strong>：数据定义语言，用来定义数据库对象；<u>create/drop/alter</u></li>
<li><strong>DML - Data Manipulation Language</strong>：数据操作语言，用来定义数据库记录；<u>Insert/delete/update</u></li>
<li><strong>DCL - Data Control Language</strong>：数据控制语言，用来定义访问权限和安全级别；</li>
</ul>
<h2 id="dql数据查询语言">DQL：数据查询语言</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="p">[</span><span class="k">DISTINCT</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">select_list</span><span class="o">&gt;</span><span class="w"> </span><span class="cm">/*要查询的列名称*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">left_table</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&lt;</span><span class="n">join_type</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">JOIN</span><span class="w"> </span><span class="o">&lt;</span><span class="n">right_table</span><span class="o">&gt;</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="o">&lt;</span><span class="n">join_condition</span><span class="o">&gt;</span><span class="cm">/*要查询的表名称*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">where_condition</span><span class="o">&gt;</span><span class="w"> </span><span class="cm">/*行条件*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">group_by_list</span><span class="o">&gt;</span><span class="w"> </span><span class="cm">/*对结果分组*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">HAVING</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">having_condition</span><span class="o">&gt;</span><span class="w"> </span><span class="cm">/*分组后的行条件*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">sorting_columns</span><span class="o">&gt;</span><span class="w"> </span><span class="p">[</span><span class="k">ASC</span><span class="o">|</span><span class="k">DESC</span><span class="p">]</span><span class="w"> </span><span class="cm">/*对结果排序*/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="o">&lt;</span><span class="n">offset_start</span><span class="p">,</span><span class="w"> </span><span class="n">row_length</span><span class="o">&gt;</span><span class="w"> </span><span class="cm">/*结果限定*/</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="mysql---执行顺序">MySQL - 执行顺序</h3>
<p>随着 Mysql 版本的更新换代，其优化器也在不断的升级，优化器会分析不同执行顺序产生的性能消耗不同而动态调整 <code>执行顺序</code>。下面是经常出现的查询顺序：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="o">&lt;</span><span class="n">left_table</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ON</span><span class="w"> </span><span class="o">&lt;</span><span class="n">join_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">&lt;</span><span class="n">join_type</span><span class="o">&gt;</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="o">&lt;</span><span class="n">right_table</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="o">&lt;</span><span class="n">where_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">&lt;</span><span class="n">group_by_list</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">HAVING</span><span class="w"> </span><span class="o">&lt;</span><span class="n">having_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">[</span><span class="k">DISTINCT</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;</span><span class="n">select_list</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">&lt;</span><span class="n">sorting_columns</span><span class="o">&gt;</span><span class="w"> </span><span class="p">[</span><span class="k">ASC</span><span class="o">|</span><span class="k">DESC</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w"> </span><span class="o">&lt;</span><span class="n">offset_start</span><span class="p">,</span><span class="w"> </span><span class="n">row_length</span><span class="o">&gt;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="condition---行筛选条件">Condition - 行筛选条件</h3>
<h4 id="in---多值匹配">IN - 多值匹配</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span><span class="n">value1</span><span class="p">,</span><span class="n">value2</span><span class="p">,...);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h4 id="like---字符匹配">LIKE - 字符匹配</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="k">LIKE</span><span class="w"> </span><span class="n">pattern</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><table>
<thead>
<tr>
<th style="text-align:left">通配符</th>
<th style="text-align:left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">%</td>
<td style="text-align:left">替代 0 个或多个字符</td>
</tr>
<tr>
<td style="text-align:left">_</td>
<td style="text-align:left">替代一个字符</td>
</tr>
<tr>
<td style="text-align:left">[<em>charlist</em>]</td>
<td style="text-align:left">字符列中的任何单一字符</td>
</tr>
<tr>
<td style="text-align:left">[^<em>charlist</em>] 或 [!<em>charlist</em>]</td>
<td style="text-align:left">不在字符列中的任何单一字符</td>
</tr>
</tbody>
</table>
<h4 id="between---范围匹配">BETWEEN - 范围匹配</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="n">value1</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">value2</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<ul>
<li><strong>AND &amp; OR 运算符</strong></li>
</ul>
<p>如果第一个条件和第二个条件都成立，则 AND 运算符显示一条记录。</p>
<p>如果第一个条件和第二个条件中只要有一个成立，则 OR 运算符显示一条记录。</p>
</blockquote>
<h3 id="having---分组筛选">HAVING - 分组筛选</h3>
<p>在 SQL 中增加 <code>HAVING</code> 子句原因是，<code>WHERE</code> 关键字无法与聚合函数 <code>GROUP BY</code> 一起使用。<code>HAVING</code> 子句可以让我们筛选分组后的各组数据。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">,</span><span class="w"> </span><span class="n">aggregate_function</span><span class="p">(</span><span class="k">column_name</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="k">operator</span><span class="w"> </span><span class="n">value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="k">column_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">HAVING</span><span class="w"> </span><span class="n">aggregate_function</span><span class="p">(</span><span class="k">column_name</span><span class="p">)</span><span class="w"> </span><span class="k">operator</span><span class="w"> </span><span class="n">value</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="toplimitrownum---结果限定">TOP/LIMIT/ROWNUM - 结果限定</h3>
<ul>
<li>SQL Server / MS Access 语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">TOP</span><span class="w"> </span><span class="nb">number</span><span class="o">|</span><span class="n">percent</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>Oracle 语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="n">ROWNUM</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nb">number</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>MySQL 语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w"> </span><span class="nb">number</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>附注：<strong>OFFSET</strong></p>
<p>为了与 PostgreSQL 兼容，MySQL 也支持句法： <code>LIMIT # OFFSET #</code></p>
<ol>
<li>
<p>selete * from testtable limit 2,1;</p>
</li>
<li>
<p>selete * from testtable limit 2 offset 1;</p>
</li>
</ol>
<p><strong>注意：</strong></p>
<ol>
<li>
<p>数据库数据计算是从 0 开始的</p>
</li>
<li>
<p>offset X 是跳过 X 个数据，limit Y 是选取 Y 个数据</p>
</li>
<li>
<p>limit X, Y 中 X 表示跳过 X 个数据，读取 Y 个数据</p>
</li>
</ol>
</blockquote>
<h3 id="as---别名">AS - 别名</h3>
<ul>
<li>列的 SQL 别名语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">alias_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>表的 SQL 别名语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">column_name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">alias_name</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p><strong>在下面的情况下，使用别名很有用：</strong></p>
<ol>
<li>
<p>在查询中涉及超过一个表</p>
</li>
<li>
<p>在查询中使用了函数</p>
</li>
<li>
<p>列名称很长或者可读性差</p>
</li>
<li>
<p>需要把两个列或者多个列结合在一起</p>
</li>
</ol>
</blockquote>
<h3 id="join---多表连接">JOIN - 多表连接</h3>
<p><img
        class="lazyload"
        data-src="https://www.runoob.com/wp-content/uploads/2019/01/sql-join.png"
        data-srcset="https://www.runoob.com/wp-content/uploads/2019/01/sql-join.png, https://www.runoob.com/wp-content/uploads/2019/01/sql-join.png 1.5x, https://www.runoob.com/wp-content/uploads/2019/01/sql-join.png 2x"
        data-sizes="auto"
        alt="https://www.runoob.com/wp-content/uploads/2019/01/sql-join.png"
        title="sql-join.png"
    /></p>
<blockquote>
<p><strong>SQL JOIN 语法：</strong></p>
<ol>
<li>
<p>INNER JOIN：如果表中有至少一个匹配，则返回行</p>
</li>
<li>
<p>LEFT JOIN：即使右表中没有匹配，也从左表返回所有的行</p>
</li>
<li>
<p>RIGHT JOIN：即使左表中没有匹配，也从右表返回所有的行</p>
</li>
<li>
<p>FULL JOIN：只要其中一个表中存在匹配，则返回行</p>
</li>
</ol>
</blockquote>
<h3 id="auto-increment---自增序列">AUTO INCREMENT - 自增序列</h3>
<p>在每次插入新记录时，自动地创建主键字段的值。</p>
<p>下面的 SQL 语句把 &ldquo;Persons&rdquo; 表中的 &ldquo;ID&rdquo; 列定义为 auto-increment 主键字段：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">ID</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="n">AUTO_INCREMENT</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">ID</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>MySQL 使用 AUTO_INCREMENT 关键字来执行 auto-increment 任务。</p>
<p>默认地，AUTO_INCREMENT 的开始值是 1，每条新记录递增 1。</p>
<p>要让 AUTO_INCREMENT 序列以其他的值起始，请使用下面的 SQL 语法：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w"> </span><span class="n">AUTO_INCREMENT</span><span class="o">=</span><span class="mi">100</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>要在 &ldquo;Persons&rdquo; 表中插入新记录，我们不必为 &ldquo;ID&rdquo; 列规定值（会自动添加一个唯一的值）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">Persons</span><span class="w"> </span><span class="p">(</span><span class="n">FirstName</span><span class="p">,</span><span class="n">LastName</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;Lars&#39;</span><span class="p">,</span><span class="s1">&#39;Monsen&#39;</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="dml数据操作语言">DML：数据操作语言</h2>
<h3 id="insert-into---插入纪录">INSERT INTO - 插入纪录</h3>
<p>有两种编写形式，第一种形式无需指定要插入数据的列名，只需提供被插入的值即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="n">value1</span><span class="p">,</span><span class="n">value2</span><span class="p">,</span><span class="n">value3</span><span class="p">,...);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>第二种形式需要指定列名及被插入的值：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">table_name</span><span class="w"> </span><span class="p">(</span><span class="n">column1</span><span class="p">,</span><span class="n">column2</span><span class="p">,</span><span class="n">column3</span><span class="p">,...)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="n">value1</span><span class="p">,</span><span class="n">value2</span><span class="p">,</span><span class="n">value3</span><span class="p">,...);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><strong>insert into select 和 select into from 的区别</strong></li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">--插入一行,要求表scorebak 必须存在
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">insert</span><span class="w"> </span><span class="k">into</span><span class="w"> </span><span class="n">scorebak</span><span class="w"> </span><span class="k">select</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">socre</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">neza</span><span class="o">=</span><span class="s1">&#39;neza&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">--也是插入一行,要求表scorebak 不存在
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">select</span><span class="w"> </span><span class="o">*</span><span class="w">  </span><span class="k">into</span><span class="w"> </span><span class="n">scorebak</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">score</span><span class="w">  </span><span class="k">where</span><span class="w"> </span><span class="n">neza</span><span class="o">=</span><span class="s1">&#39;neza&#39;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="update---更新记录">UPDATE - 更新记录</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">UPDATE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">SET</span><span class="w"> </span><span class="n">column1</span><span class="o">=</span><span class="n">value1</span><span class="p">,</span><span class="n">column2</span><span class="o">=</span><span class="n">value2</span><span class="p">,...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="n">some_column</span><span class="o">=</span><span class="n">some_value</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p><strong>请注意 SQL UPDATE 语句中的 WHERE 子句！</strong></p>
<p>WHERE 子句规定哪条记录或者哪些记录需要更新。如果您省略了 WHERE 子句，所有的记录都将被更新！</p>
</blockquote>
<h3 id="delete---删除记录">DELETE - 删除记录</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">DELETE</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="n">some_column</span><span class="o">=</span><span class="n">some_value</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p><strong>请注意 SQL DELETE 语句中的 WHERE 子句！</strong></p>
<p>WHERE 子句规定哪条记录或者哪些记录需要删除。</p>
<p>如果您省略了 WHERE 子句，所有的记录都将被删除！当然，这意味着表结构、属性、索引将保持不变。</p>
</blockquote>
<hr>
<h2 id="ddl数据定义语言">DDL：数据定义语言</h2>
<h3 id="create-database---创建数据库">CREATE DATABASE - 创建数据库</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">dbname</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="create-table---创建数据表">CREATE TABLE - 创建数据表</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name1</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name2</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name3</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">....</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>column_name 参数规定表中列的名称。</li>
<li>data_type 参数规定列的数据类型（例如 varchar、integer、decimal、date 等等）。</li>
<li>size 参数规定表中列的最大长度。</li>
</ul>
<blockquote>
<p>**提示：**如需了解 MySQL 和 SQL Server 中的数据类型，可以访问：<a href="https://www.runoob.com/sql/sql-datatypes.html" target="_blank" rel="noopener noreffer">数据类型参考手册</a></p>
</blockquote>
<h4 id="constraints---约束规则">Constraints - 约束规则</h4>
<ul>
<li>SQL CREATE TABLE + CONSTRAINT 语法</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name1</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">)</span><span class="w"> </span><span class="k">constraint_name</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name2</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">)</span><span class="w"> </span><span class="k">constraint_name</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">column_name3</span><span class="w"> </span><span class="n">data_type</span><span class="p">(</span><span class="k">size</span><span class="p">)</span><span class="w"> </span><span class="k">constraint_name</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">....</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>在 SQL 中，我们有如下约束：</p>
<ul>
<li>
<p><strong>NOT NULL</strong> - 指示某列不能存储 NULL 值</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">ID</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Age</span><span class="w"> </span><span class="nb">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 添加 NOT NULL 约束
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">MODIFY</span><span class="w"> </span><span class="n">Age</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 删除 NOT NULL 约束
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">MODIFY</span><span class="w"> </span><span class="n">Age</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NULL</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>UNIQUE</strong> - 保证某列的每行必须有唯一的值</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- CREATE TABLE 时的 SQL UNIQUE 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">UNIQUE</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">UNIQUE</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 多个列的 UNIQUE 约束
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">uc_PersonID</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">,</span><span class="n">LastName</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- uc_PersonID 是一个约束名！上面建的是唯一约束，为了方便区别约束名一般起得有规律点。
</span></span></span><span class="line"><span class="cl"><span class="c1">-- 比如 UC（就是 UNIQUE CONSTRAINT 的缩写意思是唯一约束）
</span></span></span><span class="line"><span class="cl"><span class="c1">-- uc_PersonID 就是对表中的PersonID 建唯一约束，强制约束 Id_P 和 LastName 唯一。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- ALTER TABLE 时的 SQL UNIQUE 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL / SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 多个列的 UNIQUE 约束
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">uc_PersonID</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">,</span><span class="n">LastName</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 撤销 UNIQUE 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">uc_PersonID</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">uc_PersonID</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>PRIMARY KEY</strong> - NOT NULL 和 UNIQUE 的结合</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- CREATE TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1">-- 注释：在下面的实例中，只有一个主键 PRIMARY KEY（pk_PersonID）。
</span></span></span><span class="line"><span class="cl"><span class="c1">-- 然而，pk_PersonID 的值是由两个列（P_Id 和 LastName）组成的。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">pk_PersonID</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">,</span><span class="n">LastName</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- ALTER TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- 注释：如果您使用 ALTER TABLE 语句添加主键，必须把主键列声明为不包含 NULL 值（在表首次创建时）。
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL / SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">pk_PersonID</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">,</span><span class="n">LastName</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 撤销 PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">pk_PersonID</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>FOREIGN KEY</strong> - 保证一个表中的数据匹配另一个表中的值的参照完整性</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- CREATE TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">O_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">OrderNo</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">O_Id</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w"> </span><span class="k">REFERENCES</span><span class="w"> </span><span class="n">Persons</span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">O_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">OrderNo</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="k">REFERENCES</span><span class="w"> </span><span class="n">Persons</span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">O_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">OrderNo</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">O_Id</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">fk_PerOrders</span><span class="w"> </span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">REFERENCES</span><span class="w"> </span><span class="n">Persons</span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- ALTER TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL / SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">REFERENCES</span><span class="w"> </span><span class="n">Persons</span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">fk_PerOrders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">REFERENCES</span><span class="w"> </span><span class="n">Persons</span><span class="p">(</span><span class="n">P_Id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 撤销 PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">fk_PerOrders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">fk_PerOrders</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>CHECK</strong> - 保证列中的值符合指定的条件</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- CREATE TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">chk_Person</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="o">&gt;</span><span class="mi">0</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">City</span><span class="o">=</span><span class="s1">&#39;Sandnes&#39;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- ALTER TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL / SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 定义多个列的 PRIMARY KEY 约束：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">chk_Person</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">P_Id</span><span class="o">&gt;</span><span class="mi">0</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">City</span><span class="o">=</span><span class="s1">&#39;Sandnes&#39;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 撤销 PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="n">chk_Person</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">chk_Person</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>DEFAULT</strong> - 规定没有给列赋值时的默认值</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- CREATE TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- My SQL / SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">P_Id</span><span class="w"> </span><span class="nb">int</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">LastName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">FirstName</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Address</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">City</span><span class="w"> </span><span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="s1">&#39;Sandnes&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- ALTER TABLE 时的 SQL PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ALTER</span><span class="w"> </span><span class="n">City</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="s1">&#39;SANDNES&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">CONSTRAINT</span><span class="w"> </span><span class="n">ab_c</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="s1">&#39;SANDNES&#39;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">City</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- Oracle：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">MODIFY</span><span class="w"> </span><span class="n">City</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="s1">&#39;SANDNES&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 撤销 PRIMARY KEY 约束
</span></span></span><span class="line"><span class="cl"><span class="c1">-- MySQL：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ALTER</span><span class="w"> </span><span class="n">City</span><span class="w"> </span><span class="k">DROP</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- SQL Server / Oracle / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">Persons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">COLUMN</span><span class="w"> </span><span class="n">City</span><span class="w"> </span><span class="k">DROP</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="create-index---创建索引">CREATE INDEX - 创建索引</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- 在表上创建一个简单的索引，允许使用重复的值：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">index_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ON</span><span class="w"> </span><span class="k">table_name</span><span class="w"> </span><span class="p">(</span><span class="k">column_name</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 在表上创建一个唯一的索引，不允许使用重复的值：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">index_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ON</span><span class="w"> </span><span class="k">table_name</span><span class="w"> </span><span class="p">(</span><span class="k">column_name</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 多列索引，可以在括号中列出这些列的名称，用逗号隔开：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">CREATE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">PIndex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ON</span><span class="w"> </span><span class="n">Persons</span><span class="w"> </span><span class="p">(</span><span class="n">LastName</span><span class="p">,</span><span class="w"> </span><span class="n">FirstName</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="alter-table---修改表">ALTER TABLE - 修改表</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- 如需在表中添加列，请使用下面的语法:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ADD</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="n">datatype</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 如需删除表中的列，请使用下面的语法
</span></span></span><span class="line"><span class="cl"><span class="c1">-- （请注意，某些数据库系统不允许这种在数据库表中删除列的方式）：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">DROP</span><span class="w"> </span><span class="k">COLUMN</span><span class="w"> </span><span class="k">column_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 要改变表中列的数据类型，请使用下面的语法：
</span></span></span><span class="line"><span class="cl"><span class="c1">-- SQL Server / MS Access：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">COLUMN</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="n">datatype</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- My SQL / Oracle：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">MODIFY</span><span class="w"> </span><span class="k">COLUMN</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="n">datatype</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- Oracle 10G 之后版本:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">MODIFY</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="n">datatype</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="drop---删除">DROP - 删除</h3>
<h4 id="drop-index---撤销索引">DROP INDEX - 撤销索引</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- 用于 MS Access 的 DROP INDEX 语法：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">DROP</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">index_name</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 用于 MS SQL Server 的 DROP INDEX 语法：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">DROP</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="k">table_name</span><span class="p">.</span><span class="n">index_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 用于 DB2/Oracle 的 DROP INDEX 语法：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">DROP</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">index_name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- 用于 MySQL 的 DROP INDEX 语法：
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w"> </span><span class="k">DROP</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">index_name</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h4 id="drop-table---撤销表">DROP TABLE - 撤销表</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">table_name</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h4 id="drop-database---撤销数据库">DROP DATABASE - 撤销数据库</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">DROP</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">database_name</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded></item><item><title>数据库书摘 01 - 《SQL 必知必会》</title><link>https://philohao.com/2020/02/20200216/</link><pubDate>Sun, 16 Feb 2020 22:28:47 +0800</pubDate><dc:creator>Jianfeng.Hao</dc:creator><author>haojianfeng1997@gmail.com (Jianfeng.Hao)</author><guid isPermaLink="true">https://philohao.com/2020/02/20200216/</guid><description>《SQL 必知必会》读书摘录，整理 SQL 查询、过滤、分组和连接等基础语法。</description><content:encoded><![CDATA[<blockquote>
<p>涉及资源列表：<br>
<a href="https://book.douban.com/subject/24250054/" target="_blank" rel="noopener noreffer">《SQL必知必会》（豆瓣）</a><br>
<a href="https://github.com/xianshenglu/document/blob/master/SQL%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A-%E4%B8%AD%E6%96%87-%E7%AC%AC4%E7%89%88.pdf" target="_blank" rel="noopener noreffer">PDF 资源（GitHub）</a></p>
</blockquote>
<h2 id="数据查询语句">数据查询语句</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="p">[</span><span class="k">DISTINCT</span><span class="o">/</span><span class="k">ALL</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">select_list</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">left_table</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&lt;</span><span class="n">join_type</span><span class="o">&gt;</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="o">&lt;</span><span class="n">right_table</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">ON</span><span class="w"> </span><span class="o">&lt;</span><span class="n">join_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">where_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">group_by_list</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">HAVING</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">having_condition</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">sorting_columns</span><span class="o">&gt;</span><span class="w"> </span><span class="p">[</span><span class="k">ASC</span><span class="o">|</span><span class="k">DESC</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="o">&lt;</span><span class="n">offset_start</span><span class="p">,</span><span class="w"> </span><span class="n">row_length</span><span class="o">&gt;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="易错点">易错点</h3>
<ul>
<li>多条 SQL 语句必须以分号（;）作分隔</li>
<li>注释语法 &ndash; 和 /**/，#大多数不行</li>
<li>检索数据（<code>SELECT</code>、<code>LIMIT</code>、<code>ORDER BY</code>）
<ul>
<li>DISTINCT 作用于所有的列，而不仅仅是跟在其后的那一列</li>
<li>与 DISTINCT 不同，DESC 关键字只应用到直接位于其前面的列名</li>
</ul>
</li>
<li>过滤数据（<code>WHERE</code>）
<ul>
<li>由于 AND 操作符比 OR 操作符优先级高，需要使用圆括号对操作符进行明确分组</li>
<li>IN 操作符最大的优点在于可以包含其他 SELECT 语句</li>
<li>通配符搜索只能用于文本字段（字符串），非文本数据类型字段不能使用通配符搜索</li>
<li>通配符 % 代表匹配任意字符，甚至可以匹配 0 个字符，但不可匹配 null</li>
</ul>
</li>
<li>计算字段
<ul>
<li>CONUT() 函数中如果指定列名，则会忽略指定列的值为空 NULL 的行；如果用 * 则不忽略</li>
<li>对于文本数据，MIN() 返回排序后最前面的行， MAX() 返回排序后最后面的行</li>
</ul>
</li>
<li>汇总数据
<ul>
<li>5个聚集函数（AVG、COUNT、MIN、MAX、SUM）都可用于指定 DISTINCT 参数的列，但唯独 COUNT(*) 不可以</li>
</ul>
</li>
<li>分组数据（<code>GROUP BY</code>、<code>HAVING</code>）
<ul>
<li>分组统计：GROUP BY 分组后进行聚集函数运算；分组排序：利用窗口函数及 OVER 子句</li>
<li>除聚集计算语句外，SELECT 语句中的每一列都必须在 GROUP BY 子句中给出</li>
<li>Having 支持所有 Where 操作符，区别在于 having 用于过滤分组，而 where 用于过滤行</li>
</ul>
</li>
<li>子查询
<ul>
<li>两种使用方法
<ul>
<li>WHERE 子句的 IN 操作符中</li>
<li>用来填充计算字段</li>
</ul>
</li>
<li>作为子查询的 SELECT 语句只能查询单个列</li>
</ul>
</li>
<li>联结表：自联结的实现需要用到表别名</li>
<li>组合查询（<code>UNION</code>）
<ul>
<li>UNION 中的每个查询必须包括相同的列、表达式或聚集函数，但各个列不需要以相同的次序列出</li>
<li>UNION 默认会从查询结果中自动去掉重复的行，如果想返回全部的行，可以使用 UNION ALL</li>
<li>在用 UNION 组合查询时，只能使用一条 ORDER BY 子句，它只能位于最后一条 SELECT 语句之后</li>
<li>UNION 在需要组合多个表的数据时也很有用，当列名写法不一致时可以借助别名来实现组合查询，检索到一个结果集</li>
</ul>
</li>
</ul>
<h3 id="背诵点">背诵点</h3>
<ul>
<li>不同平台差异点：
<ul>
<li>限制结果语句 - 不同平台实现起来并不一样——TOP、FETCH、ROWNUM、LIMIT</li>
<li>通配符 #（%/*、_/？、[]、^/!）</li>
<li>拼接字段（+/||）</li>
<li>函数</li>
</ul>
</li>
<li>WHERE 子句的条件操作符（=、&lt;&gt;/!=、&gt;、&lt;、&gt;=/!&lt;、&lt;=/!&gt;、between、is null）、AND/OR/IN/NOT/LIKE 操作符</li>
<li>函数（文本、数值、时间、系统、聚集、窗口）</li>
</ul>
<h2 id="数据操作语言">数据操作语言</h2>
<h2 id="数据定义语言">数据定义语言</h2>
]]></content:encoded></item></channel></rss>