<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Last Record｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/last-record/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>Last Record｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/last-record/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Wed, 12 Jan 2022 11:25:06 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/last-record/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>SQL LEFT JOIN only last record of right table — 4 種解決方案</title>
      <link>https://deanlin.net/blog/202201/sql-left-join-last-record/</link>
      <pubDate>Wed, 12 Jan 2022 11:25:06 +0800</pubDate>
      <guid>https://deanlin.net/blog/202201/sql-left-join-last-record/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>技術教學</category>
      <description>最近工作時剛好遇到了一個需求：「需要取得每位使用者最後的工作記錄。」使用者是一張 table，工作記錄又是ㄧ張 table；原本以為這個簡單的需求用個 leftJoin 就能瞬間搞定，結果卻搞了自己快一個晚上…因此決定把解決方案放上來，給有遇到相同問題朋友們。</description>
      <media:content url="https://deanlin.net/blog/202201/sql-left-join-last-record/images/sql-left-join-last-record-og_hu_be699148547cf0b3.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>最近工作時遇到了一個需求：「需要取得每位使用者最後的工作記錄。」使用者是一張 table，工作記錄又是ㄧ張 table；原本以為這個簡單的需求用個 leftJoin 就能瞬間搞定，結果卻搞了自己快一個晚上…因此決定把解決方案放上來，給有遇到相同問題朋友們。</p>
<p><img src="https://deanlin.net/blog/202201/sql-left-join-last-record/images/sql-left-join-last-record-01.webp" width="1400" height="739" alt="SQL LEFT JOIN only last record of right table — 4 種解決方案（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>文章大綱
一、使用線上 SQL 語法測試網站來理解＆學習這個知識
二、生成 users、user_logs 兩張 table
三、撰寫可以找出 right table「所有欄位」的 SQL
  ➤ 用 table alias name 來內部比對取得最大值
  ➤ 用 max 函式來找出最大值
四、撰寫找出 right table「最後 updated_at」的 SQL
  ➤ 用 GROUP BY 的概念搭配 MAX 函式篩選出最大值
  ➤ 用 Laravel 現成函式 subquery-joins 找出最大值
</code></pre><hr>
<h2 id="一使用線上-sql-語法測試網站來理解學習這個知識">一、使用線上 SQL 語法測試網站來理解＆學習這個知識<a class="h-anchor" href="#%e4%b8%80%e4%bd%bf%e7%94%a8%e7%b7%9a%e4%b8%8a-sql-%e8%aa%9e%e6%b3%95%e6%b8%ac%e8%a9%a6%e7%b6%b2%e7%ab%99%e4%be%86%e7%90%86%e8%a7%a3%e5%ad%b8%e7%bf%92%e9%80%99%e5%80%8b%e7%9f%a5%e8%ad%98" aria-label="這個段落的連結"></a></h2>
<p>考慮到讀者未必手上都剛好有能夠運行的資料庫環境，所以這邊推薦兩個實用的線上 SQL 語法測試網站(<a href="http://sqlfiddle.com/">SQL fiddle</a>、<a href="https://paiza.io/en/projects/new?language=mysql">MySQL Online</a>)</p>
<p>如果不知道如何使用，可以參考我之前的文章：「<a href="https://deanlin.net/blog/202102/online-sql-playgrounds/">線上 SQL 語法測試網站(SQL fiddle、MySQL Online)</a>」</p>
<hr>
<h2 id="二生成-usersuser_logs-兩張-table">二、生成 users、user_logs 兩張 table<a class="h-anchor" href="#%e4%ba%8c%e7%94%9f%e6%88%90-usersuser_logs-%e5%85%a9%e5%bc%b5-table" aria-label="這個段落的連結"></a></h2>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ff7b72">CREATE</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">TABLE</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span>(<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>id<span style="color:#6e7681"> </span>INT,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>name<span style="color:#6e7681"> </span>varchar(<span style="color:#a5d6ff">50</span>)<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">CREATE</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">TABLE</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span>(<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>id<span style="color:#6e7681"> </span>INT,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>user_id<span style="color:#6e7681"> </span>INT,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>log<span style="color:#6e7681"> </span>varchar(<span style="color:#a5d6ff">50</span>),<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>updated_at<span style="color:#6e7681"> </span><span style="color:#ff7b72">timestamp</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">1</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;John&#39;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">2</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;Yannis&#39;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">3</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;Victor&#39;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">4</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;Jimmy&#39;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">5</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">&#39;Richard&#39;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">1</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;John 工作記錄 1&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-01 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">2</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;John 工作記錄 big&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-09 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">3</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;John 工作記錄 2&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-05 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">4</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;John 工作記錄 3&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-06 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">5</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">4</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;Jimmy 工作記錄 1&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-01 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">6</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">4</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;Jimmy 工作記錄 2&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-03 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">7</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">4</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;Jimmy 工作記錄 big&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-05 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">8</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">5</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;Richard 工作記錄 big&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-06 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">INSERT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">INTO</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">VALUES</span><span style="color:#6e7681"> </span>(<span style="color:#a5d6ff">9</span>,<span style="color:#6e7681"> </span><span style="color:#a5d6ff">5</span><span style="color:#6e7681"> </span>,<span style="color:#a5d6ff">&#34;Richard 工作記錄 1&#34;</span>,<span style="color:#a5d6ff">&#34;2022-01-05 00:00:00&#34;</span>);<span style="color:#6e7681">
</span></span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/3fa4de5f05238eda29b1d2caa820870a" rel="noopener">init_users_user_logs.sql</a>（GitHub Gist）</p>
<hr>
<h2 id="三撰寫可以找出-right-table所有欄位的-sql">三：撰寫可以找出 right table「所有欄位」的 SQL<a class="h-anchor" href="#%e4%b8%89%e6%92%b0%e5%af%ab%e5%8f%af%e4%bb%a5%e6%89%be%e5%87%ba-right-table%e6%89%80%e6%9c%89%e6%ac%84%e4%bd%8d%e7%9a%84-sql" aria-label="這個段落的連結"></a></h2>
<h3 id="-用-table-alias-name-來內部比對取得最大值">用 table alias name 來內部比對取得最大值<a class="h-anchor" href="#-%e7%94%a8-table-alias-name-%e4%be%86%e5%85%a7%e9%83%a8%e6%af%94%e5%b0%8d%e5%8f%96%e5%be%97%e6%9c%80%e5%a4%a7%e5%80%bc" aria-label="這個段落的連結"></a></h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span>t1.name,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>t2.log,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>t2.updated_at<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>users<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681"> </span>t1<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">LEFT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">JOIN</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>(<span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span>t.<span style="color:#ff7b72;font-weight:bold">*</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span>t<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">WHERE</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">NOT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">EXISTS</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>(<span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span><span style="color:#a5d6ff">1</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">        </span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">        </span><span style="color:#ff7b72">WHERE</span><span style="color:#6e7681"> </span>user_id<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>t.user_id<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">          </span><span style="color:#ff7b72">AND</span><span style="color:#6e7681"> </span>updated_at<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">&gt;</span><span style="color:#6e7681"> </span>t.updated_at<span style="color:#6e7681"> </span>)<span style="color:#6e7681"> </span>)<span style="color:#6e7681"> </span>t2<span style="color:#6e7681"> </span><span style="color:#ff7b72">ON</span><span style="color:#6e7681"> </span>t2.user_id<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>t1.id<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">ORDER</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">BY</span><span style="color:#6e7681"> </span>t1.id<span style="color:#6e7681">
</span></span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/aab92233de2baf5232477ad86ec6fcb2" rel="noopener">last_record_method1.sql</a>（GitHub Gist）</p>
<figure class="figure"><img src="https://deanlin.net/blog/202201/sql-left-join-last-record/images/sql-left-join-last-record-02.webp" width="1400" height="808" alt="使用SQL fiddle 線上編譯的結果" loading="lazy" decoding="async">
  <figcaption>使用<a href="http://sqlfiddle.com/">SQL fiddle</a> 線上編譯的結果</figcaption>
</figure>

<h3 id="-用-max-函式來找出最大值">用 max 函式來找出最大值<a class="h-anchor" href="#-%e7%94%a8-max-%e5%87%bd%e5%bc%8f%e4%be%86%e6%89%be%e5%87%ba%e6%9c%80%e5%a4%a7%e5%80%bc" aria-label="這個段落的連結"></a></h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span>users.name,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>user_logs.log,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>user_logs.updated_at<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span>users<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">LEFT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">JOIN</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681"> </span><span style="color:#ff7b72">ON</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>users<span style="color:#ff7b72;font-weight:bold">`</span>.<span style="color:#ff7b72;font-weight:bold">`</span>id<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_logs<span style="color:#ff7b72;font-weight:bold">`</span>.<span style="color:#ff7b72;font-weight:bold">`</span>user_id<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">AND</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_logs<span style="color:#ff7b72;font-weight:bold">`</span>.<span style="color:#ff7b72;font-weight:bold">`</span>updated_at<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>(<span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">max</span>(updated_at)<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span>user_logs<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">WHERE</span><span style="color:#6e7681"> </span>user_logs.user_id<span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span>users.id)<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">ORDER</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">BY</span><span style="color:#6e7681"> </span>users.id<span style="color:#6e7681">
</span></span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/3f4ad3b36da6c68921c002d04cf89734" rel="noopener">last_record_method2.sql</a>（GitHub Gist）</p>
<figure class="figure"><img src="https://deanlin.net/blog/202201/sql-left-join-last-record/images/sql-left-join-last-record-03.webp" width="1400" height="808" alt="使用SQL fiddle 線上編譯的結果" loading="lazy" decoding="async">
  <figcaption>使用<a href="http://sqlfiddle.com/">SQL fiddle</a> 線上編譯的結果</figcaption>
</figure>

<blockquote>
<p><strong>特別提醒</strong>：上述方案在同個 user 的 user_logs 有[年月日時分秒]完全相同的「updated_at」時，會跳出複數筆資料；但此情境在正常環境中不會發生，若想避免此狀況，可以使用 distinct 函式來將 user 過濾。</p>
</blockquote>
<hr>
<h2 id="四撰寫找出-right-table最後-updated_at的-sql">四、撰寫找出 right table「最後 updated_at」的 SQL<a class="h-anchor" href="#%e5%9b%9b%e6%92%b0%e5%af%ab%e6%89%be%e5%87%ba-right-table%e6%9c%80%e5%be%8c-updated_at%e7%9a%84-sql" aria-label="這個段落的連結"></a></h2>
<p>有時我們只是要找出使用者最後更新的日期（updated_at），就不必大費周章抓出所有欄位，下面也提供兩個方案。</p>
<h3 id="-用-group-by-的概念搭配-max-函式篩選出最大值">用 GROUP BY 的概念搭配 MAX 函式篩選出最大值<a class="h-anchor" href="#-%e7%94%a8-group-by-%e7%9a%84%e6%a6%82%e5%bf%b5%e6%90%ad%e9%85%8d-max-%e5%87%bd%e5%bc%8f%e7%af%a9%e9%81%b8%e5%87%ba%e6%9c%80%e5%a4%a7%e5%80%bc" aria-label="這個段落的連結"></a></h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span>name,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">       </span>updated_at<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>users<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#ff7b72">LEFT</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">JOIN</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">  </span>(<span style="color:#ff7b72">SELECT</span><span style="color:#6e7681"> </span>user_id,<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">          </span><span style="color:#ff7b72">MAX</span>(updated_at)<span style="color:#6e7681"> </span><span style="color:#ff7b72">AS</span><span style="color:#6e7681"> </span>updated_at<span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">FROM</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_logs<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681">
</span></span></span><span style="display:flex;"><span><span style="color:#6e7681">   </span><span style="color:#ff7b72">GROUP</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">BY</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_id<span style="color:#ff7b72;font-weight:bold">`</span>)<span style="color:#6e7681"> </span><span style="color:#ff7b72">AS</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_logs<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681"> </span><span style="color:#ff7b72">ON</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>users<span style="color:#ff7b72;font-weight:bold">`</span>.<span style="color:#ff7b72;font-weight:bold">`</span>id<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#6e7681"> </span><span style="color:#ff7b72;font-weight:bold">`</span>user_logs<span style="color:#ff7b72;font-weight:bold">`</span>.<span style="color:#ff7b72;font-weight:bold">`</span>user_id<span style="color:#ff7b72;font-weight:bold">`</span><span style="color:#6e7681">
</span></span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/b18a73be311b276ea0f104258c88d573" rel="noopener">last_record_method3.sql</a>（GitHub Gist）</p>
<figure class="figure"><img src="https://deanlin.net/blog/202201/sql-left-join-last-record/images/sql-left-join-last-record-04.webp" width="1400" height="808" alt="使用SQL fiddle 線上編譯的結果" loading="lazy" decoding="async">
  <figcaption>使用<a href="http://sqlfiddle.com/">SQL fiddle</a> 線上編譯的結果</figcaption>
</figure>

<h3 id="-用-laravel-現成函式-subquery-joins-找出最大值">用 Laravel 現成函式 <a href="https://laravel.com/docs/8.x/queries#subquery-joins">subquery-joins</a> 找出最大值<a class="h-anchor" href="#-%e7%94%a8-laravel-%e7%8f%be%e6%88%90%e5%87%bd%e5%bc%8f-subquery-joins-%e6%89%be%e5%87%ba%e6%9c%80%e5%a4%a7%e5%80%bc" aria-label="這個段落的連結"></a></h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#79c0ff">$latestLogs</span> <span style="color:#ff7b72;font-weight:bold">=</span> DB<span style="color:#ff7b72;font-weight:bold">::</span>table(<span style="color:#a5d6ff">&#39;user_logs&#39;</span>)
</span></span><span style="display:flex;"><span>                <span style="color:#ff7b72;font-weight:bold">-&gt;</span>select(<span style="color:#a5d6ff">&#39;user_id&#39;</span>, DB<span style="color:#ff7b72;font-weight:bold">::</span>raw(<span style="color:#a5d6ff">&#39;MAX(updated_at) as last_log_created_at&#39;</span>))
</span></span><span style="display:flex;"><span>                <span style="color:#ff7b72;font-weight:bold">-&gt;</span>groupBy(<span style="color:#a5d6ff">&#39;user_id&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#79c0ff">$users</span> <span style="color:#ff7b72;font-weight:bold">=</span> DB<span style="color:#ff7b72;font-weight:bold">::</span>table(<span style="color:#a5d6ff">&#39;users&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72;font-weight:bold">-&gt;</span>joinSub(<span style="color:#79c0ff">$latestLogs</span>, <span style="color:#a5d6ff">&#39;latest_logs&#39;</span>, <span style="color:#ff7b72">function</span> (<span style="color:#79c0ff">$join</span>) {
</span></span><span style="display:flex;"><span>            <span style="color:#79c0ff">$join</span><span style="color:#ff7b72;font-weight:bold">-&gt;</span>on(<span style="color:#a5d6ff">&#39;users.id&#39;</span>, <span style="color:#a5d6ff">&#39;=&#39;</span>, <span style="color:#a5d6ff">&#39;latest_logs.user_id&#39;</span>);
</span></span><span style="display:flex;"><span>        })<span style="color:#ff7b72;font-weight:bold">-&gt;</span>get();
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/c3f98ae4141dd457ae25e9c2feeaf0d3" rel="noopener">last_record_method4.php</a>（GitHub Gist）</p>
<hr>
<blockquote class="pullquote"><p><em>希望今天這篇文章有幫助讀者解決工作或是專案上的需求喔～</em></p>
</blockquote>
]]></content:encoded>
    </item>
  </channel>
</rss>
