<?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>Solutions｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/solutions/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>Solutions｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/solutions/</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>Tue, 28 Nov 2023 12:12:46 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/solutions/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>問對問題，就解決一半的問題 ── 設計思考系列文</title>
      <link>https://deanlin.net/blog/202311/ask-the-right-questions/</link>
      <pubDate>Tue, 28 Nov 2023 12:12:46 +0800</pubDate>
      <guid>https://deanlin.net/blog/202311/ask-the-right-questions/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>今年我到很多企業分享 AI 工具的應用，除了介紹使用場景外，也花了不少時間講解「定義問題」的方式。</description>
      <media:content url="https://deanlin.net/blog/202311/ask-the-right-questions/images/ask-the-right-questions-og_hu_363e4a09a5b1b053.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>今年我到很多企業分享 AI 工具的應用，除了介紹使用場景外，也花了不少時間講解「定義問題」的方式。</p>
<p>因為 AI 跟人類一樣，如果你沒辦法清晰、具體的描述問題，你只會得到模稜兩可、不符預期的結果。</p>
<p>如果你覺得 AI、人類無法給你期待的答案，其實很多時候是因為根本沒把問題表達清楚，因此造成垃圾進，垃圾出 (Garbage in, garbage out) 的結果。</p>
<p><img src="https://deanlin.net/blog/202311/ask-the-right-questions/images/ask-the-right-questions-01.webp" width="1086" height="610" alt="問對問題，就解決一半的問題 ── 設計思考系列文（圖 1）" fetchpriority="high" decoding="async"></p>
<blockquote>
<p><strong>PS.</strong> 儘管這篇文章談的是「設計思考」，但與 AI 溝通時，設計思考也是相當重要的一環。</p>
</blockquote>
<h2 id="問題背後的問題">問題背後的問題<a class="h-anchor" href="#%e5%95%8f%e9%a1%8c%e8%83%8c%e5%be%8c%e7%9a%84%e5%95%8f%e9%a1%8c" aria-label="這個段落的連結"></a></h2>
<p>過去帶新人時，常常工作到一半就會收到私訊：「不好意思，可以問你一個問題嗎？」</p>
<p>收到訊息時，我通常會眉頭一皺，因為我根本不知道他要問什麼問題，所以先詢問他：「哪裡遇到問題了呢？」</p>
<p>新人：「我 xxx 功能做到一半卡住了。」</p>
<p>我：「為什麼會卡住？」</p>
<p>新人：「我使用 yyy 套件，但不知道 xxx 功能怎麼用。」</p>
<p>我：「你有看過套件的官方文件嗎？」</p>
<p>新人：「我看不懂官方文件。」</p>
<p>從表面來看，是新人功能做不出來；但真正的問題是「看不懂官方文件」，所以就算這次你幫了他，他下次遇到問題時還是會跑來找你。</p>
<hr>
<h2 id="不是每個人都很有耐心">不是每個人都很有耐心<a class="h-anchor" href="#%e4%b8%8d%e6%98%af%e6%af%8f%e5%80%8b%e4%ba%ba%e9%83%bd%e5%be%88%e6%9c%89%e8%80%90%e5%bf%83" aria-label="這個段落的連結"></a></h2>
<p>在上面的案例中，我問了「3」次才抵達問題核心。</p>
<p>但在職場上，每個人都很忙，即使筆者也不能保證自己每次都很有耐心。</p>
<p>如果想請對方幫忙，盡可能一開始就完善的描述問題，而不要用開放式的詢問，建議的基本架構：</p>
<ul>
<li><strong>具體說明自己遇到的問題</strong>：可以搭配圖片、文件，讓對方在最短的時間掌握問題。</li>
<li><strong>表達自己曾經做過的嘗試</strong>：即使是失敗的嘗試也列上去，否則就像是個伸手牌。</li>
<li><strong>詢問對方可以討論的時間</strong>：因為對方可能手上有事情在忙，如果沒有約時間，可能已讀後就忘記了。</li>
</ul>
<p>所以上面新人的問題就可以改成：「我想透過 yyy 套件達成 xxx 功能。但按照官方文件的範例（<a href="https://github.com/">https://github.com/</a>）實作後，還是做不出 xxx 功能，一直跑出 zzz 的錯誤訊息，不太確定是不是自己方向弄錯了。請問哪個時間點方便向您請教呢？感謝。」</p>
<blockquote>
<p>表達越完善，對方越能在短時間了解問題，以增加回覆意願，或跟你說這個問題可以跟誰詢問。</p>
</blockquote>
<hr>
<h2 id="把申論題改成選擇題">把申論題改成選擇題<a class="h-anchor" href="#%e6%8a%8a%e7%94%b3%e8%ab%96%e9%a1%8c%e6%94%b9%e6%88%90%e9%81%b8%e6%93%87%e9%a1%8c" aria-label="這個段落的連結"></a></h2>
<p>前幾篇設計思考的文章，都有談到「同理心」的重要性。</p>
<p>其實在發問前，我們可以先思考一下如果自己收到這個問題，會不會想回答，或者有什麼資訊不完整的地方。</p>
<p>當你站在對方的角度來思考，問出的問題就會不太一樣。</p>
<p>讓我們回想一下學生時期，相信大家在寫考卷的時候，比起申論題，應該更多人喜歡選擇題吧？</p>
<p>我們可以將「你覺得這個配色溫暖嗎？」這種開放式的問題，改成「你覺得 A 配色跟 B 配色哪個比較溫暖？」這類選擇題，這樣就會大幅降低對方回答的壓力。</p>
<hr>
<h2 id="把模糊的答案變精準">把模糊的答案變精準<a class="h-anchor" href="#%e6%8a%8a%e6%a8%a1%e7%b3%8a%e7%9a%84%e7%ad%94%e6%a1%88%e8%ae%8a%e7%b2%be%e6%ba%96" aria-label="這個段落的連結"></a></h2>
<p>這是一個資本主義的社會，如果目標不夠具體，就容易花了很多錢但得不到成效。</p>
<p>就拿廣告來舉例好了，任何產品都有他的受眾。</p>
<p>如果你只問客戶他們的受眾是誰，客戶可能回答：「上班族。」</p>
<p>但上班族的市場很大，從 22~65 歲都是上班族；所以你需要更近一步的詢問，比如：</p>
<ul>
<li>愛好（ex：戶外活動、逛展覽、運動、宅家裡…）</li>
<li>產業（ex：金融、科技、醫療、服務…）</li>
<li>薪資水平</li>
</ul>
<p>透過細分市場你才有辦法聚焦，如果什麼都想要，下場往往是什麼都得不到。</p>
<blockquote>
<p>以上就是「設計思考全方位」第五單元的心得筆記，如果覺得我的分享對你有幫助，歡迎 <a href="https://dean-lin.medium.com/subscribe">Follow</a> 我吸收更多知識。</p>
</blockquote>
<a class="linkcard" href="https://deanlin.net/series/design-thinking/">
  <span class="lc-body">
    <span class="lc-title">設計思考</span>
    <span class="lc-desc">一個工程師眼中的設計思考：同理、提問、定義問題，把「解決問題」變成可以練習的能力。</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 12h14M13 6l6 6-6 6"/></svg>林鼎淵 Dean Lin</span>
  </span>
</a>

]]></content:encoded>
    </item>
    <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>
