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

<channel>
	<title>資料查詢 DQL &#8211; 小人物看世界</title>
	<atom:link href="https://blog.che-ya.com/category/sql-tutorial/dql/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.che-ya.com</link>
	<description>軟體工程師的技術筆記</description>
	<lastBuildDate>Wed, 08 Apr 2026 08:08:15 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.che-ya.com/wp-content/uploads/2021/08/cropped-APP_icon-32x32.png</url>
	<title>資料查詢 DQL &#8211; 小人物看世界</title>
	<link>https://blog.che-ya.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>SQL 字串函數</title>
		<link>https://blog.che-ya.com/sql-string-functions/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Sun, 10 May 2026 02:53:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[SQL 教學]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=611</guid>

					<description><![CDATA[SQL 字串函數介紹 (SQL String Functions) 這篇 SQL 字串函數教學將帶你認識 SQ ... <a title="SQL 字串函數" class="read-more" href="https://blog.che-ya.com/sql-string-functions/" aria-label="Read more about SQL 字串函數">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">SQL 字串函數介紹 (SQL String Functions)</h2>



<p>這篇 SQL 字串函數教學將帶你認識 SQL 中最常用的字串處理函數，包括 CONCAT、SUBSTRING、TRIM、REPLACE、UPPER、LOWER 與 LENGTH。這些函數能幫助你在查詢時對文字資料進行串接、擷取、去除空白、替換、大小寫轉換等操作。</p>



<p>在實際開發中，資料庫儲存的文字資料經常需要進行格式處理，例如去除前後空白、統一大小寫、拼接姓名欄位等。熟練運用字串函數可以讓你的 SQL 查詢更加靈活，也能有效提升資料處理的效率。</p>



<p>以下範例將使用這張 <strong>employees</strong> 資料表來示範：</p>



<figure class="wp-block-table"><table><thead><tr><th>EmployeeID</th><th>FirstName</th><th>LastName</th><th>Email</th><th>Department</th></tr></thead><tbody><tr><td>1</td><td>  小明  </td><td>王</td><td>ming.wang@example.com</td><td>Sales</td></tr><tr><td>2</td><td>小華</td><td>李</td><td>hua.li@EXAMPLE.COM</td><td>Marketing</td></tr><tr><td>3</td><td>  小美</td><td>陳</td><td>mei.chen@example.com</td><td>Sales</td></tr><tr><td>4</td><td>小強</td><td>林</td><td>qiang.lin@Example.Com</td><td>Engineering</td></tr><tr><td>5</td><td>小芳  </td><td>黃</td><td>fang.huang@example.com</td><td>Marketing</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">CONCAT 字串串接 (SQL CONCAT Function)</h2>



<p>CONCAT 函數用來將兩個或多個字串串接在一起。在實務上經常用於合併姓名、拼接地址等情境。</p>



<h3 class="wp-block-heading">CONCAT 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">CONCAT(string1, string2, ...)

-- 或使用 || 運算子（部分資料庫支援）
string1 || string2</code></pre>



<h3 class="wp-block-heading">CONCAT 用法範例 (Example)</h3>



<p>將 LastName 與 FirstName 合併為完整姓名：</p>



<pre class="wp-block-code"><code class="">SELECT CONCAT(LastName, FirstName) AS FullName
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>FullName</th></tr></thead><tbody><tr><td>王小明</td></tr><tr><td>李小華</td></tr><tr><td>陳小美</td></tr><tr><td>林小強</td></tr><tr><td>黃小芳</td></tr></tbody></table></figure>



<p>如果想在姓名中間加入分隔符號，可以在 CONCAT 中加入字串：</p>



<pre class="wp-block-code"><code class="">SELECT CONCAT(LastName, ' ', FirstName) AS FullName
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>FullName</th></tr></thead><tbody><tr><td>王 小明</td></tr><tr><td>李 小華</td></tr><tr><td>陳 小美</td></tr><tr><td>林 小強</td></tr><tr><td>黃 小芳</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">SUBSTRING 字串擷取 (SQL SUBSTRING Function)</h2>



<p>SUBSTRING 函數用來從字串中擷取指定位置和長度的子字串。不同資料庫可能使用不同的函數名稱，例如 MySQL 也支援 SUBSTR。</p>



<h3 class="wp-block-heading">SUBSTRING 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">SUBSTRING(string, start, length)

-- MySQL 也可以寫成
SUBSTR(string, start, length)</code></pre>



<p>其中 <strong>start</strong> 是起始位置（從 1 開始計算），<strong>length</strong> 是要擷取的字元數。</p>



<h3 class="wp-block-heading">SUBSTRING 用法範例 (Example)</h3>



<p>從 Email 欄位中擷取 @ 符號前的使用者名稱（取前 3 個字元）：</p>



<pre class="wp-block-code"><code class="">SELECT Email, SUBSTRING(Email, 1, 3) AS EmailPrefix
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>Email</th><th>EmailPrefix</th></tr></thead><tbody><tr><td>ming.wang@example.com</td><td>min</td></tr><tr><td>hua.li@EXAMPLE.COM</td><td>hua</td></tr><tr><td>mei.chen@example.com</td><td>mei</td></tr><tr><td>qiang.lin@Example.Com</td><td>qia</td></tr><tr><td>fang.huang@example.com</td><td>fan</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">TRIM 去除空白 (SQL TRIM Function)</h2>



<p>TRIM 函數用來去除字串前後的空白字元（或指定字元）。在資料清理時非常實用，因為使用者輸入的資料很容易包含多餘的空白。除了 TRIM 之外，還有 LTRIM（去除左側空白）和 RTRIM（去除右側空白）。</p>



<h3 class="wp-block-heading">TRIM 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">TRIM(string)
LTRIM(string)
RTRIM(string)

-- 去除指定字元（部分資料庫支援）
TRIM(BOTH 'x' FROM string)
TRIM(LEADING 'x' FROM string)
TRIM(TRAILING 'x' FROM string)</code></pre>



<h3 class="wp-block-heading">TRIM 用法範例 (Example)</h3>



<p>去除 FirstName 欄位前後的空白：</p>



<pre class="wp-block-code"><code class="">SELECT FirstName, TRIM(FirstName) AS TrimmedName
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>FirstName</th><th>TrimmedName</th></tr></thead><tbody><tr><td>&nbsp; 小明 &nbsp;</td><td>小明</td></tr><tr><td>小華</td><td>小華</td></tr><tr><td>&nbsp; 小美</td><td>小美</td></tr><tr><td>小強</td><td>小強</td></tr><tr><td>小芳 &nbsp;</td><td>小芳</td></tr></tbody></table></figure>



<p>可以看到原本 FirstName 欄位中包含的前後空白都已被清除。</p>



<h2 class="wp-block-heading">REPLACE 字串替換 (SQL REPLACE Function)</h2>



<p>REPLACE 函數用來將字串中指定的子字串替換為另一個字串。常用於資料清理、統一格式或後置處理場景。</p>



<h3 class="wp-block-heading">REPLACE 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">REPLACE(string, old_substring, new_substring)</code></pre>



<h3 class="wp-block-heading">REPLACE 用法範例 (Example)</h3>



<p>將 Email 中的網域從 example.com 替換為 company.com：</p>



<pre class="wp-block-code"><code class="">SELECT Email, REPLACE(Email, 'example.com', 'company.com') AS NewEmail
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>Email</th><th>NewEmail</th></tr></thead><tbody><tr><td>ming.wang@example.com</td><td>ming.wang@company.com</td></tr><tr><td>hua.li@EXAMPLE.COM</td><td>hua.li@EXAMPLE.COM</td></tr><tr><td>mei.chen@example.com</td><td>mei.chen@company.com</td></tr><tr><td>qiang.lin@Example.Com</td><td>qiang.lin@Example.Com</td></tr><tr><td>fang.huang@example.com</td><td>fang.huang@company.com</td></tr></tbody></table></figure>



<p>請注意 REPLACE 是<strong>區分大小寫</strong>的，所以 EXAMPLE.COM 和 Example.Com 並沒有被替換。如果需要不區分大小寫進行替換，可以搭配 LOWER 或 UPPER 一起使用。</p>



<h2 class="wp-block-heading">UPPER 與 LOWER 大小寫轉換 (SQL UPPER / LOWER Function)</h2>



<p>UPPER 將字串轉換為大寫，LOWER 將字串轉換為小寫。這兩個函數在需要統一資料格式或進行不區分大小寫的比對時非常實用。</p>



<h3 class="wp-block-heading">UPPER / LOWER 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">UPPER(string)
LOWER(string)

-- MySQL 也支援
UCASE(string)
LCASE(string)</code></pre>



<h3 class="wp-block-heading">UPPER / LOWER 用法範例 (Example)</h3>



<p>將 Email 欄位全部轉為小寫：</p>



<pre class="wp-block-code"><code class="">SELECT Email, LOWER(Email) AS LowerEmail
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>Email</th><th>LowerEmail</th></tr></thead><tbody><tr><td>ming.wang@example.com</td><td>ming.wang@example.com</td></tr><tr><td>hua.li@EXAMPLE.COM</td><td>hua.li@example.com</td></tr><tr><td>mei.chen@example.com</td><td>mei.chen@example.com</td></tr><tr><td>qiang.lin@Example.Com</td><td>qiang.lin@example.com</td></tr><tr><td>fang.huang@example.com</td><td>fang.huang@example.com</td></tr></tbody></table></figure>



<p>將 Department 欄位全部轉為大寫：</p>



<pre class="wp-block-code"><code class="">SELECT Department, UPPER(Department) AS UpperDept
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>UpperDept</th></tr></thead><tbody><tr><td>Sales</td><td>SALES</td></tr><tr><td>Marketing</td><td>MARKETING</td></tr><tr><td>Sales</td><td>SALES</td></tr><tr><td>Engineering</td><td>ENGINEERING</td></tr><tr><td>Marketing</td><td>MARKETING</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">LENGTH 字串長度 (SQL LENGTH Function)</h2>



<p>LENGTH 函數用來取得字串的長度（字元數）。在 SQL Server 中對應的函數為 LEN，Oracle 也支援 LENGTH。</p>



<h3 class="wp-block-heading">LENGTH 語法 (Syntax)</h3>



<pre class="wp-block-code"><code class="">LENGTH(string)     -- MySQL, PostgreSQL, Oracle
LEN(string)        -- SQL Server
CHAR_LENGTH(string) -- 標準 SQL</code></pre>



<h3 class="wp-block-heading">LENGTH 用法範例 (Example)</h3>



<p>查詢每位員工的 Email 長度：</p>



<pre class="wp-block-code"><code class="">SELECT Email, LENGTH(Email) AS EmailLength
FROM employees;</code></pre>



<p>執行結果：</p>



<figure class="wp-block-table"><table><thead><tr><th>Email</th><th>EmailLength</th></tr></thead><tbody><tr><td>ming.wang@example.com</td><td>21</td></tr><tr><td>hua.li@EXAMPLE.COM</td><td>18</td></tr><tr><td>mei.chen@example.com</td><td>20</td></tr><tr><td>qiang.lin@Example.Com</td><td>21</td></tr><tr><td>fang.huang@example.com</td><td>22</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">字串函數綜合比較</h2>



<p>以下表格整理了本文介紹的各個字串函數及其功能：</p>



<figure class="wp-block-table"><table><thead><tr><th>函數</th><th>功能說明</th><th>範例</th></tr></thead><tbody><tr><td>CONCAT</td><td>字串串接</td><td>CONCAT(&#8216;A&#8217;, &#8216;B&#8217;) → &#8216;AB&#8217;</td></tr><tr><td>SUBSTRING</td><td>擷取子字串</td><td>SUBSTRING(&#8216;Hello&#8217;, 1, 3) → &#8216;Hel&#8217;</td></tr><tr><td>TRIM</td><td>去除前後空白</td><td>TRIM(&#8216;  Hi  &#8216;) → &#8216;Hi&#8217;</td></tr><tr><td>REPLACE</td><td>字串替換</td><td>REPLACE(&#8216;abc&#8217;, &#8216;b&#8217;, &#8216;x&#8217;) → &#8216;axc&#8217;</td></tr><tr><td>UPPER</td><td>轉換為大寫</td><td>UPPER(&#8216;hello&#8217;) → &#8216;HELLO&#8217;</td></tr><tr><td>LOWER</td><td>轉換為小寫</td><td>LOWER(&#8216;HELLO&#8217;) → &#8216;hello&#8217;</td></tr><tr><td>LENGTH</td><td>取得字串長度</td><td>LENGTH(&#8216;Hello&#8217;) → 5</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">各資料庫字串函數對照</h2>



<p>不同資料庫系統對字串函數的支援稍有差異，以下是常見的對照表：</p>



<figure class="wp-block-table"><table><thead><tr><th>功能</th><th>MySQL</th><th>PostgreSQL</th><th>SQL Server</th><th>Oracle</th></tr></thead><tbody><tr><td>字串串接</td><td>CONCAT / ||</td><td>CONCAT / ||</td><td>CONCAT / +</td><td>CONCAT / ||</td></tr><tr><td>擷取子字串</td><td>SUBSTRING / SUBSTR</td><td>SUBSTRING</td><td>SUBSTRING</td><td>SUBSTR</td></tr><tr><td>去除空白</td><td>TRIM / LTRIM / RTRIM</td><td>TRIM / LTRIM / RTRIM</td><td>TRIM / LTRIM / RTRIM</td><td>TRIM / LTRIM / RTRIM</td></tr><tr><td>字串替換</td><td>REPLACE</td><td>REPLACE</td><td>REPLACE</td><td>REPLACE</td></tr><tr><td>轉大寫</td><td>UPPER / UCASE</td><td>UPPER</td><td>UPPER</td><td>UPPER</td></tr><tr><td>轉小寫</td><td>LOWER / LCASE</td><td>LOWER</td><td>LOWER</td><td>LOWER</td></tr><tr><td>字串長度</td><td>LENGTH / CHAR_LENGTH</td><td>LENGTH</td><td>LEN</td><td>LENGTH</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-tutorial/">SQL 教學 — 完整教學導覽</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT — 資料查詢語法</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE — 條件查詢教學</a></li>



<li><a href="https://blog.che-ya.com/sql-like/">SQL LIKE — 模糊查詢教學</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數 — COUNT、SUM、AVG、MIN、MAX</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE — 條件判斷教學</a></li>



<li><a href="https://blog.che-ya.com/sql-null/">SQL NULL 值處理 — IS NULL、COALESCE、IFNULL</a></li>



<li><a href="https://blog.che-ya.com/sql-date/">SQL Date — 日期函數教學</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-string-functions%2F&amp;linkname=SQL%20%E5%AD%97%E4%B8%B2%E5%87%BD%E6%95%B8" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-string-functions%2F&amp;linkname=SQL%20%E5%AD%97%E4%B8%B2%E5%87%BD%E6%95%B8" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-string-functions%2F&amp;linkname=SQL%20%E5%AD%97%E4%B8%B2%E5%87%BD%E6%95%B8" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-string-functions%2F&#038;title=SQL%20%E5%AD%97%E4%B8%B2%E5%87%BD%E6%95%B8" data-a2a-url="https://blog.che-ya.com/sql-string-functions/" data-a2a-title="SQL 字串函數"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL NULL 值處理</title>
		<link>https://blog.che-ya.com/sql-null/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Tue, 28 Apr 2026 02:46:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=602</guid>

					<description><![CDATA[NULL 值介紹 (SQL NULL Value) 這篇 SQL NULL 值處理教學將帶你認識 NULL 的 ... <a title="SQL NULL 值處理" class="read-more" href="https://blog.che-ya.com/sql-null/" aria-label="Read more about SQL NULL 值處理">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">NULL 值介紹 (SQL NULL Value)</h2>



<p>這篇 SQL NULL 值處理教學將帶你認識 NULL 的基本概念與常見處理方式。在 SQL 中，NULL 代表「無值」或「未知值」，它既不是 0、也不是空字串，而是一個特殊的標記，表示該欄位沒有資料。</p>



<p>當資料表中的某個欄位沒有被賦予值時，該欄位就會自動存入 NULL。由於 NULL 不等於任何值（甚至不等於另一個 NULL），因此在查詢或運算時需要特別注意處理方式，否則可能會得到意想不到的結果。</p>



<h2 class="wp-block-heading">IS NULL 與 IS NOT NULL 語法 (Syntax)</h2>



<pre class="wp-block-code"><code class="">SELECT column_name
FROM table_name
WHERE column_name IS NULL;

SELECT column_name
FROM table_name
WHERE column_name IS NOT NULL;</code></pre>



<p>說明：</p>



<figure class="wp-block-table"><table><thead><tr>語法說明</tr></thead><tbody><tr>IS NULL判斷欄位值是否為 NULL</tr><tr>IS NOT NULL判斷欄位值是否不為 NULL</tr></tbody></table></figure>



<p>注意：不能使用 <code>= NULL</code> 或 <code>&lt;> NULL</code> 來判斷 NULL 值，因為 NULL 與任何值的比較結果都是 UNKNOWN，而非 TRUE 或 FALSE。必須使用 <code>IS NULL</code> 或 <code>IS NOT NULL</code> 來判斷。</p>



<h2 class="wp-block-heading">IS NULL 與 IS NOT NULL 用法 (Example)</h2>



<p>假設我們有一個員工資料表 employees 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr>NameDepartmentPhoneSalary</tr></thead><tbody><tr>張一業務部02-1234567835000</tr><tr>王二資訊部NULL42000</tr><tr>李三NULL07-1234567838000</tr><tr>趙四資訊部03-12345678NULL</tr><tr>陳五人資部NULL40000</tr></tbody></table></figure>



<h3 class="wp-block-heading">查詢欄位為 NULL 的資料</h3>



<p>使用 IS NULL 可以查詢某個欄位值為 NULL 的資料列。例如，查詢沒有填寫電話的員工：</p>



<pre class="wp-block-code"><code class="">SELECT Name, Phone
FROM employees
WHERE Phone IS NULL;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>NamePhone</tr></thead><tbody><tr>王二NULL</tr><tr>陳五NULL</tr></tbody></table></figure>



<h3 class="wp-block-heading">查詢欄位不為 NULL 的資料</h3>



<p>使用 IS NOT NULL 可以查詢某個欄位值不為 NULL 的資料列。例如，查詢有填寫部門的員工：</p>



<pre class="wp-block-code"><code class="">SELECT Name, Department
FROM employees
WHERE Department IS NOT NULL;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>NameDepartment</tr></thead><tbody><tr>張一業務部</tr><tr>王二資訊部</tr><tr>趙四資訊部</tr><tr>陳五人資部</tr></tbody></table></figure>



<h2 class="wp-block-heading">COALESCE 函數 (SQL COALESCE Function)</h2>



<p>COALESCE 是 SQL 標準函數，用來從一組參數中回傳第一個非 NULL 的值。如果所有參數都是 NULL，則回傳 NULL。COALESCE 是處理 NULL 值最常用也最通用的函數，幾乎所有主流資料庫都支援。</p>



<h3 class="wp-block-heading">COALESCE 語法</h3>



<pre class="wp-block-code"><code class="">COALESCE(value1, value2, ..., valueN)</code></pre>



<p>COALESCE 會依序檢查每個參數，回傳第一個不是 NULL 的值。常見用法是將可能為 NULL 的欄位替換成預設值。</p>



<h3 class="wp-block-heading">COALESCE 用法範例</h3>



<p>使用前面的 employees 資料表，將 NULL 的電話欄位顯示為「未提供」：</p>



<pre class="wp-block-code"><code class="">SELECT Name, COALESCE(Phone, '未提供') AS Phone
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>NamePhone</tr></thead><tbody><tr>張一02-12345678</tr><tr>王二未提供</tr><tr>李三07-12345678</tr><tr>趙四03-12345678</tr><tr>陳五未提供</tr></tbody></table></figure>



<p>也可以提供多個替代值，COALESCE 會依序檢查，回傳第一個非 NULL 的值：</p>



<pre class="wp-block-code"><code class="">SELECT Name, COALESCE(Phone, Department, '無資料') AS contact_info
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>Namecontact_info</tr></thead><tbody><tr>張一02-12345678</tr><tr>王二資訊部</tr><tr>李三07-12345678</tr><tr>趙四03-12345678</tr><tr>陳五人資部</tr></tbody></table></figure>



<h2 class="wp-block-heading">各資料庫的 NULL 處理函數</h2>



<p>除了通用的 COALESCE 之外，不同的資料庫系統也提供了各自專屬的 NULL 處理函數。這些函數的功能類似，都是在欄位值為 NULL 時回傳替代值，但語法和名稱有所不同。</p>



<figure class="wp-block-table"><table><thead><tr>資料庫函數說明</tr></thead><tbody><tr>MySQLIFNULL(expr, alt)若 expr 為 NULL 則回傳 alt</tr><tr>OracleNVL(expr, alt)若 expr 為 NULL 則回傳 alt</tr><tr>SQL ServerISNULL(expr, alt)若 expr 為 NULL 則回傳 alt</tr><tr>所有資料庫COALESCE(v1, v2, &#8230;)回傳第一個非 NULL 的值（SQL 標準）</tr></tbody></table></figure>



<h3 class="wp-block-heading">MySQL IFNULL 用法</h3>



<p>MySQL 的 IFNULL 函數接受兩個參數，若第一個參數為 NULL，則回傳第二個參數的值：</p>



<pre class="wp-block-code"><code class="">-- MySQL
SELECT Name, IFNULL(Salary, 0) AS Salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>NameSalary</tr></thead><tbody><tr>張一35000</tr><tr>王二42000</tr><tr>李三38000</tr><tr>趙四0</tr><tr>陳五40000</tr></tbody></table></figure>



<h3 class="wp-block-heading">Oracle NVL 用法</h3>



<p>Oracle 的 NVL 函數功能與 IFNULL 相同，語法也類似：</p>



<pre class="wp-block-code"><code class="">-- Oracle
SELECT Name, NVL(Salary, 0) AS Salary
FROM employees;</code></pre>



<p>查詢結果與上方 IFNULL 範例相同。Oracle 還提供了 NVL2 函數，可以針對 NULL 和非 NULL 分別指定不同的回傳值：</p>



<pre class="wp-block-code"><code class="">-- Oracle NVL2(expr, not_null_value, null_value)
SELECT Name, NVL2(Phone, '已填寫', '未填寫') AS phone_status
FROM employees;</code></pre>



<h3 class="wp-block-heading">SQL Server ISNULL 用法</h3>



<p>SQL Server 的 ISNULL 函數功能同樣類似：</p>



<pre class="wp-block-code"><code class="">-- SQL Server
SELECT Name, ISNULL(Salary, 0) AS Salary
FROM employees;</code></pre>



<p>建議：如果需要跨資料庫相容，優先使用 COALESCE，因為它是 SQL 標準語法，所有主流資料庫都支援。</p>



<h2 class="wp-block-heading">NULL 與聚合函數</h2>



<p>在使用<a href="https://blog.che-ya.com/sql-aggregate-functions/">聚合函數</a>時，NULL 值的處理方式是一個重要的觀念。大多數聚合函數（如 SUM、AVG、MIN、MAX）會自動忽略 NULL 值，而 COUNT 的行為則取決於參數。</p>



<pre class="wp-block-code"><code class="">-- COUNT(*) 計算所有資料列（包含 NULL）
SELECT COUNT(*) AS total_rows
FROM employees;

-- COUNT(column) 只計算該欄位非 NULL 的資料列
SELECT COUNT(Salary) AS has_salary
FROM employees;

-- AVG 會忽略 NULL 值
SELECT AVG(Salary) AS avg_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>查詢結果說明</tr></thead><tbody><tr>COUNT(*)5計算所有資料列，包含有 NULL 的列</tr><tr>COUNT(Salary)4只計算 Salary 不為 NULL 的列（趙四被排除）</tr><tr>AVG(Salary)38750(35000+42000+38000+40000)/4，忽略 NULL</tr></tbody></table></figure>



<p>特別注意 AVG 的計算：因為趙四的 Salary 為 NULL 被忽略，所以平均值是四筆資料的平均 (35000+42000+38000+40000)/4 = 38750，而不是除以 5。如果你希望將 NULL 視為 0 來計算，可以搭配 COALESCE 使用：</p>



<pre class="wp-block-code"><code class="">SELECT AVG(COALESCE(Salary, 0)) AS avg_salary
FROM employees;
-- 結果：(35000+42000+38000+0+40000)/5 = 31000</code></pre>



<h2 class="wp-block-heading">NULL 與排序 (ORDER BY)</h2>



<p>使用 <a href="https://blog.che-ya.com/sql-order-by/">ORDER BY</a> 排序時，NULL 值的排列位置因資料庫而異。在 MySQL 和 SQL Server 中，NULL 被視為最小值，升序排序時會出現在最前面；在 Oracle 和 PostgreSQL 中，NULL 被視為最大值，升序排序時會出現在最後面。</p>



<pre class="wp-block-code"><code class="">SELECT Name, Salary
FROM employees
ORDER BY Salary ASC;</code></pre>



<p>PostgreSQL 和 Oracle 支援 NULLS FIRST 和 NULLS LAST 語法，可以明確指定 NULL 的排列位置：</p>



<pre class="wp-block-code"><code class="">-- PostgreSQL / Oracle
SELECT Name, Salary
FROM employees
ORDER BY Salary ASC NULLS LAST;</code></pre>



<h2 class="wp-block-heading">NULL 運算注意事項</h2>



<p>NULL 在運算中有一些特殊的行為，這些是使用 SQL 時必須注意的重點：</p>



<figure class="wp-block-table"><table><thead><tr>運算結果說明</tr></thead><tbody><tr>NULL = NULLUNKNOWNNULL 不等於 NULL</tr><tr>NULL &lt;&gt; NULLUNKNOWNNULL 也不「不等於」NULL</tr><tr>NULL + 10NULL任何值與 NULL 做算術運算結果都是 NULL</tr><tr>NULL = &#8221;UNKNOWNNULL 不等於空字串</tr><tr>NULL AND TRUEUNKNOWNNULL 參與邏輯運算結果可能是 UNKNOWN</tr><tr>NULL OR TRUETRUEOR 運算中只要一方為 TRUE 結果就是 TRUE</tr></tbody></table></figure>



<p>由於 NULL 與任何值的算術運算結果都是 NULL，在計算欄位時要特別注意。例如：</p>



<pre class="wp-block-code"><code class="">SELECT Name, Salary, Salary * 12 AS annual_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr>NameSalaryannual_salary</tr></thead><tbody><tr>張一35000420000</tr><tr>王二42000504000</tr><tr>李三38000456000</tr><tr>趙四NULLNULL</tr><tr>陳五40000480000</tr></tbody></table></figure>



<p>趙四的 Salary 為 NULL，所以 NULL * 12 的結果仍然是 NULL。若要避免這種情況，可以搭配 COALESCE 將 NULL 替換為 0：</p>



<pre class="wp-block-code"><code class="">SELECT Name, COALESCE(Salary, 0) * 12 AS annual_salary
FROM employees;</code></pre>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT — 資料查詢語法</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE — 條件查詢教學</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數 — COUNT、SUM、AVG、MIN、MAX</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE — 條件判斷教學</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY — 排序教學</a></li>



<li><a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY — 分組統計教學</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN — 多表連接查詢</a></li>



<li><a href="https://blog.che-ya.com/create-table/">CREATE TABLE — 建立資料表</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-null%2F&amp;linkname=SQL%20NULL%20%E5%80%BC%E8%99%95%E7%90%86" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-null%2F&amp;linkname=SQL%20NULL%20%E5%80%BC%E8%99%95%E7%90%86" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-null%2F&amp;linkname=SQL%20NULL%20%E5%80%BC%E8%99%95%E7%90%86" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-null%2F&#038;title=SQL%20NULL%20%E5%80%BC%E8%99%95%E7%90%86" data-a2a-url="https://blog.che-ya.com/sql-null/" data-a2a-title="SQL NULL 值處理"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL CTE</title>
		<link>https://blog.che-ya.com/sql-cte/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Mon, 20 Apr 2026 01:57:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=591</guid>

					<description><![CDATA[CTE 簡介 (SQL CTE) 這篇 SQL CTE 教學將帶你認識 CTE（Common Table Ex ... <a title="SQL CTE" class="read-more" href="https://blog.che-ya.com/sql-cte/" aria-label="Read more about SQL CTE">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">CTE 簡介 (SQL CTE)</h2>



<p>這篇 SQL CTE 教學將帶你認識 CTE（Common Table Expression，通用表格運算式）的基本概念與用法。CTE 透過 <code>WITH</code> 關鍵字定義一個暫時的結果集，讓你可以在後續的查詢中直接引用，大幅提升複雜查詢的可讀性與維護性。</p>



<p>你可以把 CTE 想像成一個「暫時的虛擬表」，它只在當次查詢中有效，不會真正儲存在資料庫中。相較於 <code>Subquery</code>（子查詢），CTE 將複雜的子查詢抽出來獨立命名，不僅更容易閱讀，還能在同一查詢中被多次引用。</p>



<p>以下是 Subquery 與 CTE 的主要差異：</p>



<figure class="wp-block-table"><table><thead><tr><th>比較項目</th><th>Subquery</th><th>CTE</th></tr></thead><tbody><tr><td>定義位置</td><td>嵌套在查詢內部</td><td>用 WITH 定義在查詢之前</td></tr><tr><td>可讀性</td><td>複雜時較難閱讀</td><td>結構清晰，易於理解</td></tr><tr><td>可重複引用</td><td>不行，需重複寫</td><td>可以在同一查詢中多次引用</td></tr><tr><td>遞迴支援</td><td>不支援</td><td>支援遞迴 CTE</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">CTE 語法 (SQL CTE Syntax)</h2>



<pre class="wp-block-code"><code class="">WITH cte_name AS (
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition
)
SELECT column1, column2, ...
FROM cte_name;</code></pre>



<p>說明：</p>



<figure class="wp-block-table"><table><thead><tr><th>關鍵字</th><th>說明</th></tr></thead><tbody><tr><td>WITH</td><td>用來定義 CTE 的開頭關鍵字</td></tr><tr><td>cte_name</td><td>自訂的 CTE 名稱，可以在後續查詢中引用</td></tr><tr><td>AS (&#8230;)</td><td>CTE 的查詢定義，括號內放入 SELECT 查詢</td></tr><tr><td>SELECT &#8230; FROM cte_name</td><td>主查詢，引用 CTE 的結果集進行後續操作</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">CTE 用法 (Example)</h2>



<p>假設我們有一個員工資料表 employees 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE 教學</a>）：</p>



<figure class="wp-block-table"><table><thead><tr><th>EmployeeID</th><th>Name</th><th>Department</th><th>Salary</th></tr></thead><tbody><tr><td>1</td><td>張一</td><td>業務部</td><td>35000</td></tr><tr><td>2</td><td>王二</td><td>資訊部</td><td>42000</td></tr><tr><td>3</td><td>李三</td><td>業務部</td><td>38000</td></tr><tr><td>4</td><td>趙四</td><td>資訊部</td><td>45000</td></tr><tr><td>5</td><td>陳五</td><td>人資部</td><td>40000</td></tr><tr><td>6</td><td>林六</td><td>業務部</td><td>36000</td></tr><tr><td>7</td><td>黃七</td><td>資訊部</td><td>48000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">基本 CTE 用法</h3>



<p>使用 CTE 查詢各部門的平均薪資，並篩選出平均薪資超過 40000 的部門。</p>



<pre class="wp-block-code"><code class="">WITH dept_avg AS (
    SELECT Department, AVG(Salary) AS avg_salary
    FROM employees
    GROUP BY Department
)
SELECT Department, avg_salary
FROM dept_avg
WHERE avg_salary > 40000;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>45000</td></tr></tbody></table></figure>



<p>在這個範例中，我們先用 CTE 定義了 <code>dept_avg</code>，計算各部門的平均薪資，然後在主查詢中直接引用 <code>dept_avg</code> 來篩選結果。這樣的寫法比嵌套子查詢更容易理解。</p>



<h3 class="wp-block-heading">CTE 搭配 JOIN</h3>



<p>CTE 的結果集可以像一般資料表一樣與其他表進行 <code>JOIN</code>。例如，先用 CTE 計算各部門的平均薪資，再與原始資料表 JOIN，找出薪資高於部門平均的員工。</p>



<pre class="wp-block-code"><code class="">WITH dept_avg AS (
    SELECT Department, AVG(Salary) AS avg_salary
    FROM employees
    GROUP BY Department
)
SELECT e.Name, e.Department, e.Salary, d.avg_salary
FROM employees e
JOIN dept_avg d ON e.Department = d.Department
WHERE e.Salary > d.avg_salary;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>avg_salary</th></tr></thead><tbody><tr><td>李三</td><td>業務部</td><td>38000</td><td>36333</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>45000</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>45000</td></tr></tbody></table></figure>



<p>透過 CTE，我們將「計算部門平均薪資」的邏輯抽出來獨立命名，主查詢只需專注在篩選條件，程式碼更加清晰。</p>



<h2 class="wp-block-heading">多個 CTE 定義</h2>



<p>你可以在同一個 <code>WITH</code> 子句中定義多個 CTE，各個 CTE 之間用逗號分隔。後方的 CTE 可以引用前方已定義的 CTE。</p>



<pre class="wp-block-code"><code class="">WITH dept_stats AS (
    SELECT Department,
           COUNT(*) AS headcount,
           AVG(Salary) AS avg_salary
    FROM employees
    GROUP BY Department
),
high_salary_depts AS (
    SELECT Department, avg_salary
    FROM dept_stats
    WHERE avg_salary > 38000
)
SELECT * FROM high_salary_depts;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>45000</td></tr><tr><td>人資部</td><td>40000</td></tr></tbody></table></figure>



<p>第一個 CTE <code>dept_stats</code> 計算各部門的人數與平均薪資，第二個 CTE <code>high_salary_depts</code> 引用前者的結果來篩選平均薪資超過 38000 的部門。這種層層拆解的方式讓查詢邏輯更容易理解。</p>



<h2 class="wp-block-heading">遞迴 CTE (Recursive CTE)</h2>



<p>CTE 最強大的功能之一就是支援遞迴查詢。遞迴 CTE 可以在定義中引用自己，適合用於處理階層式資料（如組織架構、樹狀結構）或產生序列資料。</p>



<p>遞迴 CTE 的基本結構包含兩個部分：</p>



<figure class="wp-block-table"><table><thead><tr><th>部分</th><th>說明</th></tr></thead><tbody><tr><td>錨點查詢（Anchor）</td><td>遞迴的起始條件，不引用 CTE 自身</td></tr><tr><td>遞迴查詢（Recursive）</td><td>引用 CTE 自身，每次執行會產生新的資料列</td></tr><tr><td>UNION ALL</td><td>將錨點查詢與遞迴查詢的結果合併</td></tr></tbody></table></figure>



<pre class="wp-block-code"><code class="">WITH RECURSIVE cte_name AS (
    -- 錨點查詢（起始條件）
    SELECT ...
    UNION ALL
    -- 遞迴查詢（引用自己）
    SELECT ...
    FROM cte_name
    WHERE 終止條件
)
SELECT * FROM cte_name;</code></pre>



<p>注意：在 MySQL 中使用 <code>WITH RECURSIVE</code>，而 SQL Server 只需要 <code>WITH</code> 即可支援遞迴。</p>



<h3 class="wp-block-heading">產生數字序列</h3>



<p>使用遞迴 CTE 產生 1 到 5 的數字序列：</p>



<pre class="wp-block-code"><code class="">WITH RECURSIVE numbers AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n + 1
    FROM numbers
    WHERE n &lt; 5
)
SELECT n FROM numbers;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>n</th></tr></thead><tbody><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>3</td></tr><tr><td>4</td></tr><tr><td>5</td></tr></tbody></table></figure>



<p>錨點查詢 <code>SELECT 1 AS n</code> 產生第一筆資料 n=1，遞迴查詢每次將 n 加 1，直到 <code>n &lt; 5</code> 條件不成立時停止。</p>



<h3 class="wp-block-heading">階層式資料查詢</h3>



<p>假設我們有一個員工與主管的階層資料表 staff：</p>



<figure class="wp-block-table"><table><thead><tr><th>EmployeeID</th><th>Name</th><th>ManagerID</th></tr></thead><tbody><tr><td>1</td><td>王總</td><td>NULL</td></tr><tr><td>2</td><td>李經理</td><td>1</td></tr><tr><td>3</td><td>張組長</td><td>2</td></tr><tr><td>4</td><td>陳員工</td><td>3</td></tr><tr><td>5</td><td>林員工</td><td>2</td></tr></tbody></table></figure>



<p>使用遞迴 CTE 查詢王總下屬的所有員工及其層級：</p>



<pre class="wp-block-code"><code class="">WITH RECURSIVE org_tree AS (
    -- 錨點：從王總開始
    SELECT EmployeeID, Name, ManagerID, 0 AS level
    FROM staff
    WHERE ManagerID IS NULL
    UNION ALL
    -- 遞迴：找出下屬員工
    SELECT s.EmployeeID, s.Name, s.ManagerID, ot.level + 1
    FROM staff s
    JOIN org_tree ot ON s.ManagerID = ot.EmployeeID
)
SELECT EmployeeID, Name, level
FROM org_tree
ORDER BY level, EmployeeID;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>EmployeeID</th><th>Name</th><th>level</th></tr></thead><tbody><tr><td>1</td><td>王總</td><td>0</td></tr><tr><td>2</td><td>李經理</td><td>1</td></tr><tr><td>3</td><td>張組長</td><td>2</td></tr><tr><td>5</td><td>林員工</td><td>2</td></tr><tr><td>4</td><td>陳員工</td><td>3</td></tr></tbody></table></figure>



<p>遞迴 CTE 從最高層的王總（level=0）開始，每次遞迴找出下一層的員工，直到沒有更多下屬為止。這種查詢在處理組織架構、分類階層等情境非常實用。</p>



<h2 class="wp-block-heading">CTE 與 Subquery 的比較</h2>



<p>同一個查詢通常可以用 CTE 或 Subquery 實現。以下用「查詢平均薪資超過 40000 的部門」來比較兩種寫法。</p>



<p>使用 Subquery：</p>



<pre class="wp-block-code"><code class="">SELECT Department, avg_salary
FROM (
    SELECT Department, AVG(Salary) AS avg_salary
    FROM employees
    GROUP BY Department
) AS dept_avg
WHERE avg_salary > 40000;</code></pre>



<p>使用 CTE：</p>



<pre class="wp-block-code"><code class="">WITH dept_avg AS (
    SELECT Department, AVG(Salary) AS avg_salary
    FROM employees
    GROUP BY Department
)
SELECT Department, avg_salary
FROM dept_avg
WHERE avg_salary > 40000;</code></pre>



<p>兩種寫法的結果完全相同，但 CTE 將子查詢抽出來獨立命名，當查詢變得複雜時，CTE 的可讀性明顯更好。特別是當同一個子查詢需要被多次引用時，CTE 可以避免重複撰寫相同的查詢。</p>



<h2 class="wp-block-heading">CTE 使用注意事項</h2>



<figure class="wp-block-table"><table><thead><tr><th>注意事項</th><th>說明</th></tr></thead><tbody><tr><td>作用範圍</td><td>CTE 只在緊接其後的單一 SQL 敘述中有效</td></tr><tr><td>不儲存資料</td><td>CTE 不會建立實際的資料表，只是暫時的結果集</td></tr><tr><td>遞迴限制</td><td>遞迴 CTE 需設定終止條件，否則可能無限迴圈。各資料庫預設遞迴上限不同</td></tr><tr><td>資料庫支援</td><td>MySQL 8.0+、PostgreSQL、SQL Server、Oracle、SQLite 3.8.3+ 等皆支援</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-having/">SQL HAVING</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-view/">SQL VIEW</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-cte%2F&amp;linkname=SQL%20CTE" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-cte%2F&amp;linkname=SQL%20CTE" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-cte%2F&amp;linkname=SQL%20CTE" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-cte%2F&#038;title=SQL%20CTE" data-a2a-url="https://blog.che-ya.com/sql-cte/" data-a2a-title="SQL CTE"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL Window Functions</title>
		<link>https://blog.che-ya.com/sql-window-functions/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Thu, 16 Apr 2026 02:39:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=586</guid>

					<description><![CDATA[窗口函數 (SQL Window Functions) 這篇 SQL Window Functions 教學將 ... <a title="SQL Window Functions" class="read-more" href="https://blog.che-ya.com/sql-window-functions/" aria-label="Read more about SQL Window Functions">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">窗口函數 (SQL Window Functions)</h2>



<p>這篇 SQL Window Functions 教學將帶你認識窗口函數（Window Functions）的基本概念與用法。窗口函數可以在不改變查詢結果列數的情況下，對每一列進行計算，例如排名、編號、取前後列的值等。與<a href="https://blog.che-ya.com/sql-aggregate-functions/">聚合函數</a>不同的是，窗口函數不會將多列合併為一列，而是保留每一列的原始資料，並在旁邊新增計算結果。</p>



<p>窗口函數常用於排名、分組排序、計算累計值、取得前後列資料等場景。搭配 OVER() 子句來定義「窗口」的範圍，可以指定分組（PARTITION BY）與排序（ORDER BY）方式。常見的窗口函數包括 ROW_NUMBER()、RANK()、DENSE_RANK()、LEAD()、LAG() 等。</p>



<h2 class="wp-block-heading">Window Functions 語法 (SQL Window Functions Syntax)</h2>



<pre class="wp-block-code"><code>SELECT column_name,
       window_function() OVER (
           PARTITION BY column_name
           ORDER BY column_name
       ) AS alias
FROM table_name;</code></pre>



<p>說明：</p>



<figure class="wp-block-table"><table><thead><tr><th>關鍵字</th><th>說明</th></tr></thead><tbody><tr><td>window_function()</td><td>窗口函數名稱，例如 ROW_NUMBER()、RANK()、LEAD() 等</td></tr><tr><td>OVER()</td><td>定義窗口的範圍，是窗口函數必備的子句</td></tr><tr><td>PARTITION BY</td><td>（選填）指定分組欄位，類似 GROUP BY，但不會合併資料列</td></tr><tr><td>ORDER BY</td><td>（選填）指定窗口內的排序方式</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Window Functions 用法 (Example)</h2>



<p>假設我們有一個員工資料表 employees 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th></tr></thead><tbody><tr><td>張一</td><td>業務部</td><td>35000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">ROW_NUMBER() — 依序編號</h3>



<p>ROW_NUMBER() 會為每一列依照指定的排序方式，從 1 開始依序給予不重複的編號。即使有相同的值，編號也不會重複。</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       ROW_NUMBER() OVER (ORDER BY Salary DESC) AS row_num
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>row_num</th></tr></thead><tbody><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>1</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>2</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>3</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td><td>4</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td><td>5</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>6</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>7</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">RANK() — 排名（有間隔）</h3>



<p>RANK() 會依照指定的排序方式給予排名。如果有相同的值，會給予相同的排名，但下一個排名會跳過。例如有兩個第 1 名，下一個就是第 3 名（跳過第 2 名）。</p>



<p>為了更清楚地展示 RANK() 的特性，假設員工資料中王二與陳五的薪資都是 42000：</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       RANK() OVER (ORDER BY Salary DESC) AS rank_num
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>rank_num</th></tr></thead><tbody><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>1</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>2</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>3</td></tr><tr><td>陳五</td><td>人資部</td><td>42000</td><td>3</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td><td>5</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>6</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>7</td></tr></tbody></table></figure>



<p>可以看到王二與陳五薪資相同，都是第 3 名，而下一個排名直接跳到第 5 名（跳過第 4 名）。</p>



<h3 class="wp-block-heading">DENSE_RANK() — 排名（無間隔）</h3>



<p>DENSE_RANK() 與 RANK() 類似，也會對相同值給予相同排名，但不同的是，下一個排名不會跳過，而是連續的。</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       DENSE_RANK() OVER (ORDER BY Salary DESC) AS dense_rank_num
FROM employees;</code></pre>



<p>同樣假設王二與陳五的薪資都是 42000，查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>dense_rank_num</th></tr></thead><tbody><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>1</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>2</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>3</td></tr><tr><td>陳五</td><td>人資部</td><td>42000</td><td>3</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td><td>4</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>5</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>6</td></tr></tbody></table></figure>



<p>與 RANK() 相比，DENSE_RANK() 在王二與陳五（都是第 3 名）之後，下一個排名是第 4 名而不是第 5 名。</p>



<h3 class="wp-block-heading">ROW_NUMBER vs RANK vs DENSE_RANK 比較</h3>



<p>以下整理三個排名函數的差異：</p>



<figure class="wp-block-table"><table><thead><tr><th>函數</th><th>相同值的處理</th><th>排名是否連續</th></tr></thead><tbody><tr><td>ROW_NUMBER()</td><td>即使值相同，編號也不重複</td><td>連續（1, 2, 3, 4&#8230;）</td></tr><tr><td>RANK()</td><td>相同值給予相同排名</td><td>不連續，會跳過（1, 2, 2, 4&#8230;）</td></tr><tr><td>DENSE_RANK()</td><td>相同值給予相同排名</td><td>連續，不跳過（1, 2, 2, 3&#8230;）</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">LAG() — 取前一列的值</h3>



<p>LAG() 可以取得目前列的前 N 列（預設為前 1 列）的值，常用於比較當前資料與前一筆資料的差異，例如計算薪資差距、月營收變化等。</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       LAG(Salary, 1) OVER (ORDER BY Salary DESC) AS prev_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>prev_salary</th></tr></thead><tbody><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>NULL</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>48000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>45000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td><td>42000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td><td>40000</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>38000</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>36000</td></tr></tbody></table></figure>



<p>第一列因為沒有前一列，所以 prev_salary 為 NULL。每一列的 prev_salary 就是依照薪資由高到低排序後，前一筆員工的薪資。</p>



<h3 class="wp-block-heading">LEAD() — 取後一列的值</h3>



<p>LEAD() 與 LAG() 相反，可以取得目前列的後 N 列（預設為後 1 列）的值。常用於預測或比較下一筆資料。</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       LEAD(Salary, 1) OVER (ORDER BY Salary DESC) AS next_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>next_salary</th></tr></thead><tbody><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>45000</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>42000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>40000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td><td>38000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td><td>36000</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>35000</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>NULL</td></tr></tbody></table></figure>



<p>最後一列因為沒有後一列，所以 next_salary 為 NULL。</p>



<h3 class="wp-block-heading">PARTITION BY 搭配窗口函數 — 分組內排名</h3>



<p>PARTITION BY 可以將資料依照指定欄位分組，讓窗口函數在每個分組內分別計算。這類似 <a href="https://blog.che-ya.com/sql-group-by/">GROUP BY</a> 的分組概念，但不會將資料合併。</p>



<p>例如，依部門分組，在每個部門內依薪資由高到低排名：</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       ROW_NUMBER() OVER (
           PARTITION BY Department
           ORDER BY Salary DESC
       ) AS dept_rank
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>dept_rank</th></tr></thead><tbody><tr><td>李三</td><td>業務部</td><td>38000</td><td>1</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>2</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>3</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td><td>1</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>1</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>2</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>3</td></tr></tbody></table></figure>



<p>可以看到每個部門的排名都是從 1 開始重新計算，這就是 PARTITION BY 的作用。</p>



<h3 class="wp-block-heading">搭配 LAG() 計算薪資差距</h3>



<p>結合 PARTITION BY 與 LAG()，可以在每個部門內計算員工與前一位員工的薪資差距：</p>



<pre class="wp-block-code"><code>SELECT Name, Department, Salary,
       LAG(Salary, 1) OVER (
           PARTITION BY Department
           ORDER BY Salary DESC
       ) AS prev_salary,
       Salary - LAG(Salary, 1) OVER (
           PARTITION BY Department
           ORDER BY Salary DESC
       ) AS salary_diff
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th><th>prev_salary</th><th>salary_diff</th></tr></thead><tbody><tr><td>李三</td><td>業務部</td><td>38000</td><td>NULL</td><td>NULL</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td><td>38000</td><td>-2000</td></tr><tr><td>張一</td><td>業務部</td><td>35000</td><td>36000</td><td>-1000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td><td>NULL</td><td>NULL</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td><td>NULL</td><td>NULL</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td><td>48000</td><td>-3000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td><td>45000</td><td>-3000</td></tr></tbody></table></figure>



<p>每個部門的第一位員工因為沒有前一列，所以 prev_salary 和 salary_diff 都是 NULL。這個查詢可以清楚看出每個部門內員工之間的薪資差距。</p>



<h3 class="wp-block-heading">常見窗口函數一覽</h3>



<p>除了本篇介紹的函數之外，SQL 還提供許多其他窗口函數，以下為常見的窗口函數整理：</p>



<figure class="wp-block-table"><table><thead><tr><th>函數</th><th>說明</th></tr></thead><tbody><tr><td>ROW_NUMBER()</td><td>依序給予不重複的列編號</td></tr><tr><td>RANK()</td><td>排名，相同值同名次，有間隔</td></tr><tr><td>DENSE_RANK()</td><td>排名，相同值同名次，無間隔</td></tr><tr><td>LAG(col, n)</td><td>取前 n 列的值（預設 n=1）</td></tr><tr><td>LEAD(col, n)</td><td>取後 n 列的值（預設 n=1）</td></tr><tr><td>FIRST_VALUE(col)</td><td>取窗口內第一列的值</td></tr><tr><td>LAST_VALUE(col)</td><td>取窗口內最後一列的值</td></tr><tr><td>NTILE(n)</td><td>將資料平均分成 n 組</td></tr><tr><td>SUM() OVER()</td><td>計算累計加總</td></tr><tr><td>AVG() OVER()</td><td>計算移動平均</td></tr></tbody></table></figure>



<p>窗口函數是 SQL 進階查詢中非常強大的工具，能夠在不改變結果集的情況下進行複雜的計算。搭配 PARTITION BY 和 ORDER BY，可以靈活地對資料進行分組排名、前後比較等操作。如果你需要對分組結果進行篩選，可以參閱 <a href="https://blog.che-ya.com/sql-having/">SQL HAVING</a> 教學。</p>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY</a></li>



<li><a href="https://blog.che-ya.com/sql-having/">SQL HAVING</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>



<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-distinct/">SQL DISTINCT</a></li>



<li><a href="https://blog.che-ya.com/sql-as/">SQL AS</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-window-functions%2F&amp;linkname=SQL%20Window%20Functions" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-window-functions%2F&amp;linkname=SQL%20Window%20Functions" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-window-functions%2F&amp;linkname=SQL%20Window%20Functions" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-window-functions%2F&#038;title=SQL%20Window%20Functions" data-a2a-url="https://blog.che-ya.com/sql-window-functions/" data-a2a-title="SQL Window Functions"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL HAVING</title>
		<link>https://blog.che-ya.com/sql-having/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Sun, 12 Apr 2026 03:37:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=582</guid>

					<description><![CDATA[HAVING 篩選 (SQL HAVING) 這篇 SQL HAVING 教學將帶你認識 HAVING 子句的 ... <a title="SQL HAVING" class="read-more" href="https://blog.che-ya.com/sql-having/" aria-label="Read more about SQL HAVING">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">HAVING 篩選 (SQL HAVING)</h2>



<p>這篇 SQL HAVING 教學將帶你認識 HAVING 子句的基本概念與用法。HAVING 用來對 <code>GROUP BY</code> 分組後的結果進行條件篩選，通常搭配聚合函數（如 COUNT、SUM、AVG、MIN、MAX）一起使用。</p>



<p>你可能會好奇，<code>WHERE</code> 不是也能篩選資料嗎？沒錯，但 <code>WHERE</code> 是在分組之前篩選個別資料列，而 <code>HAVING</code> 則是在分組之後篩選分組結果。當你需要根據聚合函數的計算結果來篩選時，就必須使用 <code>HAVING</code>。</p>



<p>以下是 <code>WHERE</code> 與 <code>HAVING</code> 的主要差異：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>比較項目</th><th>WHERE</th><th>HAVING</th></tr></thead><tbody><tr><td>篩選時機</td><td>分組前（GROUP BY 之前）</td><td>分組後（GROUP BY 之後）</td></tr><tr><td>篩選對象</td><td>個別資料列</td><td>分組後的結果</td></tr><tr><td>能否使用聚合函數</td><td>不能</td><td>可以</td></tr><tr><td>常見搭配</td><td>SELECT、UPDATE、DELETE</td><td>GROUP BY + 聚合函數</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">HAVING 語法 (SQL HAVING Syntax)</h2>



<pre class="wp-block-code"><code class="">SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name
HAVING aggregate_function(column_name) condition;</code></pre>



<p>說明：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>關鍵字</th><th>說明</th></tr></thead><tbody><tr><td>SELECT</td><td>指定要查詢的欄位與聚合函數</td></tr><tr><td>FROM</td><td>指定資料來源的資料表</td></tr><tr><td>WHERE</td><td>（選填）在分組前先篩選資料列</td></tr><tr><td>GROUP BY</td><td>指定用來分組的欄位</td></tr><tr><td>HAVING</td><td>對分組後的聚合結果進行條件篩選</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">HAVING 用法 (Example)</h2>



<p>假設我們有一個員工資料表 <code>employees</code> 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE 教學</a>）：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Name</th><th>Department</th><th>Salary</th></tr></thead><tbody><tr><td>張一</td><td>業務部</td><td>35000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">篩選員工人數 &gt;= 2 的部門</h3>



<p>使用 <code>HAVING</code> 搭配 <code>COUNT()</code> 函數，可以篩選出員工人數大於或等於 2 的部門。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount
FROM employees
GROUP BY Department
HAVING COUNT(*) &gt;= 2;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th></tr></thead><tbody><tr><td>業務部</td><td>3</td></tr><tr><td>資訊部</td><td>3</td></tr></tbody></table></figure>



<p>因為人資部只有 1 位員工，不符合 <code>COUNT(*) &gt;= 2</code> 的條件，所以被篩選掉了。</p>



<h3 class="wp-block-heading">篩選平均薪資 &gt;= 40000 的部門</h3>



<p>使用 <code>HAVING</code> 搭配 <code>AVG()</code> 函數，可以篩選出平均薪資大於或等於 40000 的部門。</p>



<pre class="wp-block-code"><code class="">SELECT Department, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
HAVING AVG(Salary) &gt;= 40000;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>45000</td></tr><tr><td>人資部</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">篩選薪資總和 &gt; 100000 的部門</h3>



<p>使用 <code>HAVING</code> 搭配 <code>SUM()</code> 函數，可以篩選出薪資總和超過 100000 的部門。</p>



<pre class="wp-block-code"><code class="">SELECT Department, SUM(Salary) AS total_salary
FROM employees
GROUP BY Department
HAVING SUM(Salary) &gt; 100000;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>total_salary</th></tr></thead><tbody><tr><td>業務部</td><td>109000</td></tr><tr><td>資訊部</td><td>135000</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">搭配 WHERE 與 HAVING 一起使用</h2>



<p><code>WHERE</code> 與 <code>HAVING</code> 可以在同一個查詢中同時使用。<code>WHERE</code> 先篩選個別資料列，篩選後的結果再進行 <code>GROUP BY</code> 分組，最後由 <code>HAVING</code> 篩選分組結果。</p>



<p>例如，先排除薪資低於 36000 的員工，再篩選出平均薪資 &gt;= 40000 的部門：</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
WHERE Salary &gt;= 36000
GROUP BY Department
HAVING AVG(Salary) &gt;= 40000;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>3</td><td>45000</td></tr><tr><td>人資部</td><td>1</td><td>40000</td></tr></tbody></table></figure>



<p>執行順序為：先由 <code>WHERE</code> 排除薪資低於 36000 的張一（業務部，35000），接著 <code>GROUP BY</code> 對剩餘資料進行分組，最後 <code>HAVING</code> 篩選出平均薪資 &gt;= 40000 的部門。業務部因為平均薪資為 37000（(38000 + 36000) / 2），不符合條件而被排除。</p>



<h2 class="wp-block-heading">HAVING 搭配多個條件</h2>



<p><code>HAVING</code> 子句中可以使用 <code>AND</code>、<code>OR</code> 來組合多個條件，就像 <code>WHERE</code> 一樣。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
HAVING COUNT(*) &gt;= 2 AND AVG(Salary) &gt;= 40000;</code></pre>



<p>查詢結果如下（只有同時滿足員工人數 &gt;= 2 且平均薪資 &gt;= 40000 的部門）：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>3</td><td>45000</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">搭配 ORDER BY 排序結果</h2>



<p>篩選後的結果可以搭配 <code>ORDER BY</code> 進行排序。完整的查詢語句執行順序為：<code>WHERE</code> → <code>GROUP BY</code> → <code>HAVING</code> → <code>ORDER BY</code>。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, SUM(Salary) AS total_salary
FROM employees
GROUP BY Department
HAVING COUNT(*) &gt;= 2
ORDER BY total_salary DESC;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th><th>total_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>3</td><td>135000</td></tr><tr><td>業務部</td><td>3</td><td>109000</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">SQL 語句執行順序</h2>



<p>了解 SQL 語句的執行順序，有助於理解 <code>WHERE</code> 與 <code>HAVING</code> 的差異：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>順序</th><th>子句</th><th>說明</th></tr></thead><tbody><tr><td>1</td><td>FROM</td><td>指定資料來源</td></tr><tr><td>2</td><td>WHERE</td><td>篩選個別資料列</td></tr><tr><td>3</td><td>GROUP BY</td><td>將資料分組</td></tr><tr><td>4</td><td>HAVING</td><td>篩選分組結果</td></tr><tr><td>5</td><td>SELECT</td><td>選取要顯示的欄位</td></tr><tr><td>6</td><td>ORDER BY</td><td>排序結果</td></tr></tbody></table></figure>



<p>從執行順序可以看出，<code>WHERE</code> 在第 2 步執行（分組前），而 <code>HAVING</code> 在第 4 步執行（分組後），這就是為什麼 <code>WHERE</code> 不能使用聚合函數，而 <code>HAVING</code> 可以。</p>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>



<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-distinct/">SQL DISTINCT</a></li>



<li><a href="https://blog.che-ya.com/sql-as/">SQL AS</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-having%2F&amp;linkname=SQL%20HAVING" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-having%2F&amp;linkname=SQL%20HAVING" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-having%2F&amp;linkname=SQL%20HAVING" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-having%2F&#038;title=SQL%20HAVING" data-a2a-url="https://blog.che-ya.com/sql-having/" data-a2a-title="SQL HAVING"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL GROUP BY</title>
		<link>https://blog.che-ya.com/sql-group-by/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 02:16:00 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=580</guid>

					<description><![CDATA[GROUP BY 分組 (SQL GROUP BY) 這篇 SQL GROUP BY 教學將帶你認識 GROU ... <a title="SQL GROUP BY" class="read-more" href="https://blog.che-ya.com/sql-group-by/" aria-label="Read more about SQL GROUP BY">閱讀全文</a>]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">GROUP BY 分組 (SQL GROUP BY)</h2>



<p>這篇 SQL GROUP BY 教學將帶你認識 GROUP BY 子句的基本概念與用法。GROUP BY 用來將查詢結果依據指定欄位進行分組，通常搭配<a href="https://blog.che-ya.com/sql-aggregate-functions/">聚合函數</a>（如 COUNT、SUM、AVG、MIN、MAX）一起使用，對每個分組分別進行統計計算。</p>



<p>當你需要按照某個欄位（例如部門、類別、地區等）來彙總資料時，GROUP BY 就是最重要的工具。它會將相同值的資料列歸為同一組，再對每一組套用聚合函數，回傳每組的計算結果。</p>



<h2 class="wp-block-heading">GROUP BY 語法 (SQL GROUP BY Syntax)</h2>



<pre class="wp-block-code"><code class="">SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name;</code></pre>



<p>說明：</p>



<figure class="wp-block-table"><table><thead><tr><th>關鍵字</th><th>說明</th></tr></thead><tbody><tr><td>SELECT</td><td>指定要查詢的欄位與聚合函數</td></tr><tr><td>FROM</td><td>指定資料來源的資料表</td></tr><tr><td>WHERE</td><td>（選填）在分組前先篩選資料列</td></tr><tr><td>GROUP BY</td><td>指定用來分組的欄位</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">GROUP BY 用法 (Example)</h2>



<p>假設我們有一個員工資料表 employees 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th></tr></thead><tbody><tr><td>張一</td><td>業務部</td><td>35000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td></tr><tr><td>林六</td><td>業務部</td><td>36000</td></tr><tr><td>黃七</td><td>資訊部</td><td>48000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">依部門分組計算人數</h3>



<p>使用 GROUP BY 搭配 <a href="https://blog.che-ya.com/sql-aggregate-functions/">COUNT()</a> 函數，可以計算每個部門的員工人數。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>headcount</th></tr></thead><tbody><tr><td>業務部</td><td>3</td></tr><tr><td>資訊部</td><td>3</td></tr><tr><td>人資部</td><td>1</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">依部門分組計算平均薪資</h3>



<p>使用 GROUP BY 搭配 AVG() 函數，可以計算每個部門的平均薪資。</p>



<pre class="wp-block-code"><code class="">SELECT Department, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>avg_salary</th></tr></thead><tbody><tr><td>業務部</td><td>36333</td></tr><tr><td>資訊部</td><td>45000</td></tr><tr><td>人資部</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">依部門分組計算薪資總和</h3>



<p>使用 GROUP BY 搭配 SUM() 函數，可以計算每個部門的薪資總和。</p>



<pre class="wp-block-code"><code class="">SELECT Department, SUM(Salary) AS total_salary
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>total_salary</th></tr></thead><tbody><tr><td>業務部</td><td>109000</td></tr><tr><td>資訊部</td><td>135000</td></tr><tr><td>人資部</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">搭配 WHERE 篩選後再分組</h3>



<p>可以先用 <a href="https://blog.che-ya.com/sql-where/">WHERE</a> 篩選資料列，再用 GROUP BY 進行分組。WHERE 會在分組之前執行，只有符合條件的資料才會被納入分組。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
WHERE Salary >= 38000
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>headcount</th><th>avg_salary</th></tr></thead><tbody><tr><td>業務部</td><td>1</td><td>38000</td></tr><tr><td>資訊部</td><td>3</td><td>45000</td></tr><tr><td>人資部</td><td>1</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">依多個欄位分組</h3>



<p>GROUP BY 也可以同時指定多個欄位進行分組，資料會依據所有指定欄位的組合來分組。</p>



<pre class="wp-block-code"><code class="">SELECT Department, Salary, COUNT(*) AS count
FROM employees
GROUP BY Department, Salary;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>Salary</th><th>count</th></tr></thead><tbody><tr><td>業務部</td><td>35000</td><td>1</td></tr><tr><td>業務部</td><td>36000</td><td>1</td></tr><tr><td>業務部</td><td>38000</td><td>1</td></tr><tr><td>資訊部</td><td>42000</td><td>1</td></tr><tr><td>資訊部</td><td>45000</td><td>1</td></tr><tr><td>資訊部</td><td>48000</td><td>1</td></tr><tr><td>人資部</td><td>40000</td><td>1</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">搭配 ORDER BY 排序分組結果</h3>



<p>分組後的結果可以搭配 <a href="https://blog.che-ya.com/sql-order-by/">ORDER BY</a> 進行排序，例如依照平均薪資由高到低排列。</p>



<pre class="wp-block-code"><code class="">SELECT Department, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
ORDER BY avg_salary DESC;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>avg_salary</th></tr></thead><tbody><tr><td>資訊部</td><td>45000</td></tr><tr><td>人資部</td><td>40000</td></tr><tr><td>業務部</td><td>36333</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">搭配多個聚合函數</h3>



<p>在同一個查詢中，可以同時使用多個聚合函數來取得不同的統計資訊。</p>



<pre class="wp-block-code"><code class="">SELECT Department,
       COUNT(*) AS headcount,
       SUM(Salary) AS total_salary,
       AVG(Salary) AS avg_salary,
       MIN(Salary) AS min_salary,
       MAX(Salary) AS max_salary
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>headcount</th><th>total_salary</th><th>avg_salary</th><th>min_salary</th><th>max_salary</th></tr></thead><tbody><tr><td>業務部</td><td>3</td><td>109000</td><td>36333</td><td>35000</td><td>38000</td></tr><tr><td>資訊部</td><td>3</td><td>135000</td><td>45000</td><td>42000</td><td>48000</td></tr><tr><td>人資部</td><td>1</td><td>40000</td><td>40000</td><td>40000</td><td>40000</td></tr></tbody></table></figure>



<p>當你需要對分組後的結果進行篩選時，不能使用 WHERE（因為 WHERE 是在分組前執行的），而是要使用 HAVING 子句。想了解更多，請參閱 <a href="https://blog.che-ya.com/sql-having/">SQL HAVING</a> 教學。</p>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-having/">SQL HAVING</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>



<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-distinct/">SQL DISTINCT</a></li>



<li><a href="https://blog.che-ya.com/sql-as/">SQL AS</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-group-by%2F&amp;linkname=SQL%20GROUP%20BY" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-group-by%2F&amp;linkname=SQL%20GROUP%20BY" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-group-by%2F&amp;linkname=SQL%20GROUP%20BY" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-group-by%2F&#038;title=SQL%20GROUP%20BY" data-a2a-url="https://blog.che-ya.com/sql-group-by/" data-a2a-title="SQL GROUP BY"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL 聚合函數</title>
		<link>https://blog.che-ya.com/sql-aggregate-functions/</link>
					<comments>https://blog.che-ya.com/sql-aggregate-functions/#comments</comments>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Thu, 26 Mar 2026 10:16:56 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=426</guid>

					<description><![CDATA[聚合函數是對一組值執行計算，並返回單一值的函數。聚合函數經常與 SELECT 語句的 GROUP BY 子句一同使用。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">聚合函數 (SQL Aggregate Functions)</h2>



<p>這篇 SQL 聚合函數教學將帶你認識聚合函數的基本概念。聚合函數是對一組值執行計算，並返回單一值的函數。聚合函數經常與 <a href="https://blog.che-ya.com/sql-select/">SELECT</a> 語句的 GROUP BY 子句一同使用。</p>



<p>以下是 SQL 中常用的聚合函數：</p>



<figure class="wp-block-table"><table><thead><tr><th>函數</th><th>說明</th></tr></thead><tbody><tr><td>COUNT()</td><td>計算列數</td></tr><tr><td>SUM()</td><td>計算總和</td></tr><tr><td>AVG()</td><td>計算平均值</td></tr><tr><td>MIN()</td><td>取得最小值</td></tr><tr><td>MAX()</td><td>取得最大值</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">聚合函數語法 (SQL Aggregate Functions Syntax)</h2>



<pre class="wp-block-code"><code class="">SELECT aggregate_function(column_name)
FROM table_name
WHERE condition;</code></pre>



<h2 class="wp-block-heading">聚合函數用法 (Example)</h2>



<p>假設我們有一個員工資料表 employees 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Department</th><th>Salary</th></tr></thead><tbody><tr><td>張一</td><td>業務部</td><td>35000</td></tr><tr><td>王二</td><td>資訊部</td><td>42000</td></tr><tr><td>李三</td><td>業務部</td><td>38000</td></tr><tr><td>趙四</td><td>資訊部</td><td>45000</td></tr><tr><td>陳五</td><td>人資部</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">COUNT() 函數</h3>



<p>COUNT() 用來計算符合條件的資料列數。</p>



<pre class="wp-block-code"><code class="">SELECT COUNT(*) AS total_employees
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>total_employees</th></tr></thead><tbody><tr><td>5</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">SUM() 函數</h3>



<p>SUM() 用來計算數值欄位的總和。</p>



<pre class="wp-block-code"><code class="">SELECT SUM(Salary) AS total_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>total_salary</th></tr></thead><tbody><tr><td>200000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">AVG() 函數</h3>



<p>AVG() 用來計算數值欄位的平均值。</p>



<pre class="wp-block-code"><code class="">SELECT AVG(Salary) AS avg_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>avg_salary</th></tr></thead><tbody><tr><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">MIN() 函數</h3>



<p>MIN() 用來取得欄位中的最小值。</p>



<pre class="wp-block-code"><code class="">SELECT MIN(Salary) AS min_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>min_salary</th></tr></thead><tbody><tr><td>35000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">MAX() 函數</h3>



<p>MAX() 用來取得欄位中的最大值。</p>



<pre class="wp-block-code"><code class="">SELECT MAX(Salary) AS max_salary
FROM employees;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>max_salary</th></tr></thead><tbody><tr><td>45000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">搭配 GROUP BY 使用</h3>



<p>聚合函數經常搭配 <a href="https://blog.che-ya.com/sql-group-by/">GROUP BY</a> 子句來對分組後的資料進行統計計算。GROUP BY 會將資料依照指定的欄位進行分組，再對每個分組分別執行聚合函數，最終回傳每個分組的計算結果。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Department</th><th>headcount</th><th>avg_salary</th></tr></thead><tbody><tr><td>業務部</td><td>2</td><td>36500</td></tr><tr><td>資訊部</td><td>2</td><td>43500</td></tr><tr><td>人資部</td><td>1</td><td>40000</td></tr></tbody></table></figure>



<p>GROUP BY 的基本語法如下，將想要分組的欄位放在 GROUP BY 後方，並在 SELECT 中搭配聚合函數：</p>



<pre class="wp-block-code"><code class="">SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name;</code></pre>



<p>例如，想要查詢每個部門的員工人數與最高薪資，可以這樣寫：</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, MAX(Salary) AS max_salary
FROM employees
GROUP BY Department;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th><th>max_salary</th></tr></thead><tbody><tr><td>業務部</td><td>2</td><td>40000</td></tr><tr><td>資訊部</td><td>2</td><td>45000</td></tr><tr><td>人資部</td><td>1</td><td>40000</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">搭配 HAVING 篩選分組結果</h3>



<p>當我們需要對分組後的聚合結果進行篩選時，不能使用 <a href="https://blog.che-ya.com/sql-where/">WHERE</a>，因為 WHERE 是在分組前篩選資料列。此時需要使用 HAVING 子句，它可以針對聚合函數的計算結果進行條件篩選。</p>



<pre class="wp-block-code"><code class="">SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
HAVING COUNT(*) >= 2;</code></pre>



<p>查詢結果如下（只顯示員工人數 >= 2 的部門）：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Department</th><th>headcount</th><th>avg_salary</th></tr></thead><tbody><tr><td>業務部</td><td>2</td><td>36500</td></tr><tr><td>資訊部</td><td>2</td><td>43500</td></tr></tbody></table></figure>



<p>想了解更多 GROUP BY 的進階用法，請參閱 <a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY</a> 完整教學。</p>



<p></p>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-group-by/">SQL GROUP BY</a></li>



<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-date/">SQL Date</a></li>



<li><a href="https://blog.che-ya.com/sql-exists/">SQL EXISTS</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-aggregate-functions%2F&amp;linkname=SQL%20%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B8" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-aggregate-functions%2F&amp;linkname=SQL%20%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B8" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-aggregate-functions%2F&amp;linkname=SQL%20%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B8" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-aggregate-functions%2F&#038;title=SQL%20%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B8" data-a2a-url="https://blog.che-ya.com/sql-aggregate-functions/" data-a2a-title="SQL 聚合函數"></a></p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.che-ya.com/sql-aggregate-functions/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Date</title>
		<link>https://blog.che-ya.com/sql-date/</link>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Fri, 13 Dec 2024 06:31:48 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=187</guid>

					<description><![CDATA[一般資料庫都有提供表示日期的資料型態 (Date Data Types)。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">日期資料型態 (SQL Date Data Types)</h2>



<p>這篇 SQL 日期函數教學介紹資料庫中常用的日期資料型態與日期函數。一般資料庫都有提供表示日期的資料型態 (Date Data Types)，搭配 <a href="https://blog.che-ya.com/sql-select/">SELECT</a> 語句可以靈活查詢日期相關資料。</p>



<h2 class="wp-block-heading">MySQL 日期資料型態</h2>



<p>MySQL 中常用的日期資料型態如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>資料型態</th><th>格式</th><th>說明</th></tr></thead><tbody><tr><td>DATE</td><td>YYYY-MM-DD</td><td>日期</td></tr><tr><td>DATETIME</td><td>YYYY-MM-DD HH:MI:SS</td><td>日期與時間</td></tr><tr><td>TIMESTAMP</td><td>YYYY-MM-DD HH:MI:SS</td><td>時間戳記</td></tr><tr><td>YEAR</td><td>YYYY 或 YY</td><td>年份</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">SQL Date 函數 (SQL Date Functions)</h2>



<p>以下是一些常用的 SQL 日期函數：</p>



<figure class="wp-block-table"><table><thead><tr><th>函數</th><th>說明</th></tr></thead><tbody><tr><td>NOW()</td><td>返回目前的日期與時間</td></tr><tr><td>CURDATE()</td><td>返回目前的日期</td></tr><tr><td>CURTIME()</td><td>返回目前的時間</td></tr><tr><td>DATE()</td><td>提取日期部分</td></tr><tr><td>YEAR()</td><td>提取年份</td></tr><tr><td>MONTH()</td><td>提取月份</td></tr><tr><td>DAY()</td><td>提取日</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">日期函數用法 (Example)</h2>



<p>假設我們有一個訂單資料表 orders 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr><th>OrderId</th><th>ProductName</th><th>OrderDate</th></tr></thead><tbody><tr><td>1</td><td>蘋果</td><td>2024-11-01</td></tr><tr><td>2</td><td>香蕉</td><td>2024-11-15</td></tr><tr><td>3</td><td>橘子</td><td>2024-12-01</td></tr></tbody></table></figure>



<p>我們可以使用 DATE 函數搭配 <a href="https://blog.che-ya.com/sql-where/">WHERE</a> 子句來查詢特定日期的訂單：</p>



<pre class="wp-block-code"><code class="">SELECT * FROM orders
WHERE DATE(OrderDate) = '2024-11-01';</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>OrderId</th><th>ProductName</th><th>OrderDate</th></tr></thead><tbody><tr><td>1</td><td>蘋果</td><td>2024-11-01</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">各資料庫日期函數差異 (Date Functions Across Databases)</h2>



<p>不同的資料庫系統在日期函數的語法上有所差異，以下整理了 MySQL、SQL Server、PostgreSQL 和 Oracle 中常用的日期操作函數，幫助你在不同資料庫環境下靈活運用。</p>



<h3 class="wp-block-heading">日期格式化 (Date Formatting)</h3>



<p>將日期轉換為指定格式的字串，各資料庫的語法如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>資料庫</th><th>語法</th><th>範例</th></tr></thead><tbody><tr><td>MySQL</td><td>DATE_FORMAT(date, format)</td><td>DATE_FORMAT(NOW(), &#8216;%Y-%m-%d&#8217;)</td></tr><tr><td>SQL Server</td><td>FORMAT(date, format)</td><td>FORMAT(GETDATE(), &#8216;yyyy-MM-dd&#8217;)</td></tr><tr><td>PostgreSQL</td><td>TO_CHAR(date, format)</td><td>TO_CHAR(NOW(), &#8216;YYYY-MM-DD&#8217;)</td></tr><tr><td>Oracle</td><td>TO_CHAR(date, format)</td><td>TO_CHAR(SYSDATE, &#8216;YYYY-MM-DD&#8217;)</td></tr></tbody></table></figure>



<p>以 MySQL 為例，使用 DATE_FORMAT 將訂單日期格式化為「年/月」的格式：</p>



<pre class="wp-block-code"><code lang="sql" class="language-sql">SELECT ProductName, DATE_FORMAT(OrderDate, '%Y/%m') AS FormattedDate
FROM orders;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>ProductName</th><th>FormattedDate</th></tr></thead><tbody><tr><td>蘋果</td><td>2024/11</td></tr><tr><td>香蕉</td><td>2024/11</td></tr><tr><td>橘子</td><td>2024/12</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">日期加減運算 (Date Addition)</h3>



<p>在日期上加上或減去一段時間間隔，各資料庫的語法差異較大：</p>



<figure class="wp-block-table"><table><thead><tr><th>資料庫</th><th>語法</th><th>加 7 天的範例</th></tr></thead><tbody><tr><td>MySQL</td><td>DATE_ADD(date, INTERVAL n unit)</td><td>DATE_ADD(&#8216;2024-11-01&#8217;, INTERVAL 7 DAY)</td></tr><tr><td>SQL Server</td><td>DATEADD(unit, n, date)</td><td>DATEADD(DAY, 7, &#8216;2024-11-01&#8217;)</td></tr><tr><td>PostgreSQL</td><td>date + INTERVAL &#8216;n unit&#8217;</td><td>&#8216;2024-11-01&#8217;::date + INTERVAL &#8216;7 days&#8217;</td></tr><tr><td>Oracle</td><td>date + n（天數）</td><td>TO_DATE(&#8216;2024-11-01&#8217;, &#8216;YYYY-MM-DD&#8217;) + 7</td></tr></tbody></table></figure>



<p>以 MySQL 為例，查詢每筆訂單 7 天後的日期：</p>



<pre class="wp-block-code"><code lang="sql" class="language-sql">SELECT ProductName, OrderDate,
       DATE_ADD(OrderDate, INTERVAL 7 DAY) AS DeliveryDate
FROM orders;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>ProductName</th><th>OrderDate</th><th>DeliveryDate</th></tr></thead><tbody><tr><td>蘋果</td><td>2024-11-01</td><td>2024-11-08</td></tr><tr><td>香蕉</td><td>2024-11-15</td><td>2024-11-22</td></tr><tr><td>橘子</td><td>2024-12-01</td><td>2024-12-08</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">日期差異計算 (Date Difference)</h3>



<p>計算兩個日期之間的差異，各資料庫的寫法也不盡相同：</p>



<figure class="wp-block-table"><table><thead><tr><th>資料庫</th><th>語法</th><th>說明</th></tr></thead><tbody><tr><td>MySQL</td><td>DATEDIFF(date1, date2)</td><td>回傳天數差（date1 &#8211; date2）</td></tr><tr><td>SQL Server</td><td>DATEDIFF(unit, start, end)</td><td>可指定回傳單位（DAY、MONTH、YEAR 等）</td></tr><tr><td>PostgreSQL</td><td>date1 &#8211; date2</td><td>直接相減，回傳天數</td></tr><tr><td>Oracle</td><td>date1 &#8211; date2</td><td>直接相減，回傳天數（含小數）</td></tr></tbody></table></figure>



<p>以 MySQL 為例，計算每筆訂單距離今天過了幾天：</p>



<pre class="wp-block-code"><code lang="sql" class="language-sql">SELECT ProductName, OrderDate,
       DATEDIFF(CURDATE(), OrderDate) AS DaysAgo
FROM orders;</code></pre>



<p>了解各資料庫之間日期函數的差異，可以幫助你在切換不同資料庫環境時更快速地撰寫正確的 SQL 語句。建議在開發時先確認目標資料庫的日期函數語法，避免因語法差異導致查詢錯誤。</p>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-between/">SQL BETWEEN</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-order-by/">SQL ORDER BY</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-date%2F&amp;linkname=SQL%20Date" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-date%2F&amp;linkname=SQL%20Date" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-date%2F&amp;linkname=SQL%20Date" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-date%2F&#038;title=SQL%20Date" data-a2a-url="https://blog.che-ya.com/sql-date/" data-a2a-title="SQL Date"></a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL CASE</title>
		<link>https://blog.che-ya.com/sql-case/</link>
					<comments>https://blog.che-ya.com/sql-case/#comments</comments>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Tue, 10 Dec 2024 06:31:48 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=186</guid>

					<description><![CDATA[CASE 類似於程式語言裡的 if/then/else 語句，用來作邏輯判斷。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">CASE 關鍵字 (SQL CASE Keyword)</h2>



<p>這篇 SQL CASE 條件判斷教學介紹 CASE 關鍵字的用法。CASE 類似於程式語言裡的 if/then/else 語句，用來在 <a href="https://blog.che-ya.com/sql-select/">SELECT</a> 查詢中作邏輯判斷。</p>



<h2 class="wp-block-heading">CASE 語法 (SQL CASE Syntax)</h2>



<pre class="wp-block-code"><code class="">CASE
    WHEN condition THEN result
    [WHEN···]
    [ELSE result]
END;</code></pre>



<p>或是：</p>



<pre class="wp-block-code"><code class="">CASE expression
    WHEN value THEN result
    [WHEN···]
    [ELSE result]
END;</code></pre>



<p>若省略了 ELSE 子句且洽無相符的條件則會返回 NULL。CASE 可搭配 <a href="https://blog.che-ya.com/sql-where/">WHERE</a>、<a href="https://blog.che-ya.com/sql-order-by/">ORDER BY</a> 等子句使用。</p>



<h2 class="wp-block-heading">CASE 關鍵字用法 (Example)</h2>



<p>假設我們作一個問卷調查：您喜歡這個網站嗎？1.喜歡 2.不喜歡 3.還OK</p>



<p>問卷結果資料表 questionnaire 如下（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Answer</th></tr></thead><tbody><tr><td>張一</td><td>1</td></tr><tr><td>王二</td><td>2</td></tr><tr><td>李三</td><td>3</td></tr></tbody></table></figure>



<p>我們可以作以下這個 SQL 查詢：</p>



<pre class="wp-block-code"><code class="">SELECT Name,
    CASE Answer
        WHEN 1 THEN '喜歡'
        WHEN 2 THEN '不喜歡'
        WHEN 3 THEN '還OK'
    END AS Answer
FROM questionnaire;</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>Name</th><th>Answer</th></tr></thead><tbody><tr><td>張一</td><td>喜歡</td></tr><tr><td>王二</td><td>不喜歡</td></tr><tr><td>李三</td><td>還OK</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-exists/">SQL EXISTS</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-date/">SQL Date</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-in/">SQL IN</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-case%2F&amp;linkname=SQL%20CASE" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-case%2F&amp;linkname=SQL%20CASE" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-case%2F&amp;linkname=SQL%20CASE" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-case%2F&#038;title=SQL%20CASE" data-a2a-url="https://blog.che-ya.com/sql-case/" data-a2a-title="SQL CASE"></a></p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.che-ya.com/sql-case/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL EXISTS</title>
		<link>https://blog.che-ya.com/sql-exists/</link>
					<comments>https://blog.che-ya.com/sql-exists/#comments</comments>
		
		<dc:creator><![CDATA[ㄚ槌]]></dc:creator>
		<pubDate>Fri, 06 Dec 2024 06:31:48 +0000</pubDate>
				<category><![CDATA[資料查詢 DQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://blog.che-ya.com/?p=184</guid>

					<description><![CDATA[EXISTS 運算子可以連接子查詢，用來判斷子查詢是否有返回的結果，如果有結果返回則為真、否則為假。若 EXISTS 為真，就會繼續執行外查詢中的 SQL；若 EXISTS 為假，則整個 SQL 查詢就不會返回任何結果。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">EXISTS 運算子 (SQL EXISTS Operator)</h2>



<p>這篇 SQL EXISTS 子查詢教學介紹 EXISTS 運算子的用法。EXISTS 運算子可以連接<a href="https://blog.che-ya.com/sql-subquery/">子查詢</a>，用來判斷子查詢是否有返回的結果，如果有結果返回則為真、否則為假。若 EXISTS 為真，就會繼續執行外查詢中的 <a href="https://blog.che-ya.com/sql-select/">SQL 查詢</a>；若 EXISTS 為假，則整個 SQL 查詢就不會返回任何結果。</p>



<h2 class="wp-block-heading">EXISTS 語法 (SQL EXISTS Syntax)</h2>



<pre class="wp-block-code"><code class="">SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);</code></pre>



<h2 class="wp-block-heading">EXISTS 用法 (Example)</h2>



<p>假設我們有兩個資料表，customers 和 orders（若需了解如何建立資料表，請參考 <a href="https://blog.che-ya.com/create-table/">CREATE TABLE</a> 教學）：</p>



<p>customers 資料表：</p>



<figure class="wp-block-table"><table><thead><tr><th>CustomerID</th><th>CustomerName</th></tr></thead><tbody><tr><td>1</td><td>張一</td></tr><tr><td>2</td><td>王二</td></tr><tr><td>3</td><td>李三</td></tr></tbody></table></figure>



<p>orders 資料表：</p>



<figure class="wp-block-table"><table><thead><tr><th>OrderID</th><th>CustomerID</th><th>Product</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>蘋果</td></tr><tr><td>2</td><td>1</td><td>香蕉</td></tr><tr><td>3</td><td>3</td><td>橘子</td></tr></tbody></table></figure>



<p>使用 EXISTS 搭配 <a href="https://blog.che-ya.com/sql-where/">WHERE</a> 子句查詢有下過訂單的客戶：</p>



<pre class="wp-block-code"><code class="">SELECT CustomerName
FROM customers c
WHERE EXISTS
(SELECT 1 FROM orders o WHERE o.CustomerID = c.CustomerID);</code></pre>



<p>查詢結果如下：</p>



<figure class="wp-block-table"><table><thead><tr><th>CustomerName</th></tr></thead><tbody><tr><td>張一</td></tr><tr><td>李三</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">延伸閱讀</h2>



<ul class="wp-block-list">
<li><a href="https://blog.che-ya.com/sql-subquery/">SQL Subquery</a></li>



<li><a href="https://blog.che-ya.com/sql-case/">SQL CASE</a></li>



<li><a href="https://blog.che-ya.com/sql-where/">SQL WHERE</a></li>



<li><a href="https://blog.che-ya.com/sql-select/">SQL SELECT</a></li>



<li><a href="https://blog.che-ya.com/sql-in/">SQL IN</a></li>



<li><a href="https://blog.che-ya.com/sql-join/">SQL JOIN</a></li>



<li><a href="https://blog.che-ya.com/sql-aggregate-functions/">SQL 聚合函數</a></li>



<li><a href="https://blog.che-ya.com/sql-date/">SQL Date</a></li>
</ul>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='ㄚ槌' src='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/9914399915f96350f302945e8ddddee1a9b1995350182f513fd2e1fa816c100a?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.che-ya.com/author/a3230230/" class="vcard author" rel="author"><span class="fn">ㄚ槌</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="saboxplugin-web "><a href="https://blog.che-ya.com" target="_self" >blog.che-ya.com</a></div><div class="clearfix"></div></div></div><p><a class="a2a_button_facebook" href="https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-exists%2F&amp;linkname=SQL%20EXISTS" title="Facebook" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_line" href="https://www.addtoany.com/add_to/line?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-exists%2F&amp;linkname=SQL%20EXISTS" title="Line" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Fblog.che-ya.com%2Fsql-exists%2F&amp;linkname=SQL%20EXISTS" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Fblog.che-ya.com%2Fsql-exists%2F&#038;title=SQL%20EXISTS" data-a2a-url="https://blog.che-ya.com/sql-exists/" data-a2a-title="SQL EXISTS"></a></p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.che-ya.com/sql-exists/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
