# dbt สำหรับ Data Analyst ในปี 2026: การสร้างโมเดล การทดสอบ และคำถามสัมภาษณ์งาน > เรียนรู้ dbt สำหรับ Data Analyst ตั้งแต่การสร้างโมเดล การทดสอบข้อมูล ไปจนถึงคำถามสัมภาษณ์งานที่พบบ่อย พร้อมตัวอย่างโค้ดและแนวปฏิบัติที่ดี - Published: 2026-06-17 - Updated: 2026-06-17 - Author: SharpSkill - Tags: dbt, data-analytics, sql, data-engineering, interview - Reading time: 12 min --- dbt (data build tool) ได้กลายเป็นเครื่องมือมาตรฐานในการทำ Data Transformation สำหรับทีม Data Analytics ทั่วโลก ในปี 2026 ความสามารถในการใช้งาน dbt อย่างเชี่ยวชาญไม่ใช่ทักษะเสริมอีกต่อไป แต่เป็นความต้องการหลักของตำแหน่ง Data Analyst ในองค์กรที่ใช้ Modern Data Stack บทความนี้จะนำเสนอแนวคิดหลักของ dbt ตั้งแต่การออกแบบโมเดล การทดสอบข้อมูล ไปจนถึงคำถามที่มักพบในการสัมภาษณ์งาน > **ทำไม Data Analyst ต้องเรียนรู้ dbt** > > dbt ช่วยให้ Data Analyst สามารถเขียน SQL ที่มีโครงสร้าง ทดสอบได้ และบำรุงรักษาง่าย โดยไม่ต้องพึ่งพา Data Engineer ในการทำ Transformation ทุกครั้ง การเข้าใจ dbt จะเปิดโอกาสในสายงานและเพิ่มประสิทธิภาพการทำงานอย่างมีนัยสำคัญ ## ความเข้าใจพื้นฐานเกี่ยวกับ dbt Modeling การออกแบบโมเดลใน dbt เป็นหัวใจสำคัญของการทำ Data Analytics ที่มีประสิทธิภาพ โครงสร้างที่นิยมใช้กันอย่างแพร่หลายคือ **Staging-Intermediate-Marts** ซึ่งแบ่งการ Transform ข้อมูลออกเป็นชั้นๆ ตามวัตถุประสงค์การใช้งาน **Staging Models** ทำหน้าที่เป็นชั้นแรกที่รับข้อมูลจาก Source โดยตรง มีหน้าที่หลักคือการทำความสะอาดข้อมูล เปลี่ยนชื่อคอลัมน์ให้เป็นมาตรฐาน และกรองข้อมูลที่ไม่ต้องการออก ตัวอย่างต่อไปนี้แสดง Staging Model สำหรับข้อมูลการชำระเงินจาก Stripe: ```sql -- models/staging/stripe/stg_stripe__payments.sql with source as ( select * from {{ source('stripe', 'payments') }} ), renamed as ( select id as payment_id, amount / 100.0 as amount_usd, -- Stripe stores cents status as payment_status, created::timestamp as created_at, customer_id from source where status != 'failed' -- Filter invalid records early ) select * from renamed ``` โค้ดด้านบนแสดงให้เห็นหลักการสำคัญหลายประการ ประการแรกคือการใช้ `{{ source() }}` เพื่ออ้างอิงข้อมูลต้นทาง ซึ่งช่วยให้ dbt สามารถติดตาม Lineage ได้อย่างถูกต้อง ประการที่สองคือการแปลงหน่วยเงินจาก cents เป็น dollars ตั้งแต่ชั้น Staging เพื่อให้โมเดลชั้นถัดไปใช้งานได้ทันที และประการสุดท้ายคือการกรองข้อมูลที่ไม่ต้องการออกตั้งแต่เนิ่นๆ ## การสร้าง Mart Models สำหรับ Business Analytics **Mart Models** เป็นชั้นสุดท้ายที่ออกแบบมาเพื่อตอบคำถามทางธุรกิจโดยเฉพาะ โมเดลเหล่านี้มักจะถูก Query โดย BI Tools หรือ Dashboard โดยตรง ดังนั้นจึงต้องมีโครงสร้างที่เข้าใจง่ายและมีประสิทธิภาพในการ Query ```sql -- models/marts/finance/fct_monthly_revenue.sql with payments as ( select * from {{ ref('stg_stripe__payments') }} ), monthly as ( select date_trunc('month', created_at) as revenue_month, count(*) as total_transactions, sum(amount_usd) as gross_revenue, sum(case when payment_status = 'refunded' then amount_usd else 0 end) as refunds from payments group by 1 ) select revenue_month, total_transactions, gross_revenue, refunds, gross_revenue - refunds as net_revenue -- Key business metric from monthly ``` การใช้ `{{ ref() }}` แทนการอ้างอิงตารางโดยตรงเป็นหลักการสำคัญของ dbt เนื่องจากช่วยให้ระบบสามารถสร้าง DAG (Directed Acyclic Graph) และรัน Models ตามลำดับที่ถูกต้องโดยอัตโนมัติ นอกจากนี้ยังช่วยให้การทำ Data Lineage เป็นไปอย่างสมบูรณ์ ## การใช้ Incremental Models สำหรับข้อมูลขนาดใหญ่ เมื่อทำงานกับข้อมูลที่มีปริมาณมาก เช่น Event Logs หรือ Page Views การ Rebuild ตารางทั้งหมดในทุกครั้งที่รัน dbt อาจใช้เวลานานและสิ้นเปลืองทรัพยากร **Incremental Models** ช่วยแก้ปัญหานี้โดยการประมวลผลเฉพาะข้อมูลใหม่ที่เข้ามา ```sql -- models/marts/product/fct_page_views.sql {{ config( materialized='incremental', unique_key='page_view_id', incremental_strategy='merge' ) }} with events as ( select event_id as page_view_id, user_id, page_url, session_id, event_timestamp from {{ ref('stg_snowplow__events') }} where event_type = 'page_view' {% if is_incremental() %} -- Only process new events since last run and event_timestamp > (select max(event_timestamp) from {{ this }}) {% endif %} ) select * from events ``` การตั้งค่า `incremental_strategy='merge'` บอก dbt ให้ใช้ MERGE statement ซึ่งจะ Update แถวที่มีอยู่แล้วหาก `unique_key` ซ้ำกัน และ Insert แถวใหม่หากไม่ซ้ำ การใช้ `{{ this }}` อ้างอิงถึงตารางปัจจุบันของโมเดลนั้นเอง ## การเลือก Materialization ที่เหมาะสม การเลือก Materialization ที่ถูกต้องมีผลโดยตรงต่อประสิทธิภาพและค่าใช้จ่ายของ Data Warehouse ตารางต่อไปนี้สรุปการใช้งานแต่ละประเภท: | Materialization | Use Case | Rebuild Behavior | |----------------|----------|-------------------| | `view` | Lightweight staging models, low query frequency | Recreated as SQL view on each run | | `table` | Mart models queried often by dashboards | Full table rebuild on each run | | `incremental` | Large fact tables (events, logs) | Appends/merges new rows only | | `ephemeral` | Reusable CTEs, never queried directly | Compiled inline as subquery | Data Analyst ควรเริ่มต้นด้วย `view` สำหรับ Staging Models และ `table` สำหรับ Mart Models จากนั้นค่อยปรับเปลี่ยนเป็น `incremental` เมื่อข้อมูลมีขนาดใหญ่จนส่งผลต่อเวลาในการรัน ## การทดสอบข้อมูลด้วย dbt Tests การทดสอบข้อมูลเป็นส่วนสำคัญที่ทำให้ dbt แตกต่างจากการเขียน SQL แบบดั้งเดิม dbt รองรับการทดสอบสองประเภทหลัก ได้แก่ **Generic Tests** ที่กำหนดใน YAML และ **Singular Tests** ที่เขียนเป็น SQL แยกต่างหาก ### Generic Tests ใน YAML ```yaml # models/staging/stripe/_stripe__models.yml version: 2 models: - name: stg_stripe__payments description: "Cleaned payment records from Stripe" columns: - name: payment_id description: "Unique payment identifier" tests: - unique - not_null - name: payment_status tests: - accepted_values: values: ['succeeded', 'pending', 'refunded'] - name: amount_usd tests: - not_null - dbt_utils.expression_is_true: expression: ">= 0" # No negative payments ``` การทดสอบ `unique` และ `not_null` เป็น Generic Tests พื้นฐานที่มาพร้อมกับ dbt ส่วน `accepted_values` ใช้ตรวจสอบว่าค่าในคอลัมน์อยู่ในรายการที่กำหนดไว้เท่านั้น การใช้ `dbt_utils.expression_is_true` จาก dbt-utils package ช่วยให้สามารถเขียนเงื่อนไขที่ซับซ้อนได้ ### Singular Tests สำหรับ Business Logic เมื่อต้องการทดสอบ Business Logic ที่ซับซ้อน การเขียน Singular Test เป็น SQL จะมีความยืดหยุ่นมากกว่า: ```sql -- tests/assert_revenue_not_negative.sql -- This test fails if any month has negative net revenue select revenue_month, net_revenue from {{ ref('fct_monthly_revenue') }} where net_revenue < 0 -- Should never happen ``` หลักการของ Singular Test คือ Query ที่คืนค่าแถวใดๆ จะถือว่า Test ล้มเหลว ดังนั้น Query ด้านบนจะ Pass ก็ต่อเมื่อไม่มีเดือนใดที่มี net_revenue ติดลบ ## การใช้ Macros เพื่อลด Code Duplication **Macros** ใน dbt เปรียบเสมือน Functions ที่สามารถนำกลับมาใช้ซ้ำได้ในหลายโมเดล ช่วยลดการเขียนโค้ดซ้ำซ้อนและทำให้การบำรุงรักษาง่ายขึ้น ```sql -- macros/cents_to_dollars.sql {% macro cents_to_dollars(column_name) %} ({{ column_name }} / 100.0)::numeric(12, 2) {% endmacro %} ``` ```sql -- Usage in any model select payment_id, {{ cents_to_dollars('amount_cents') }} as amount_usd, {{ cents_to_dollars('tax_cents') }} as tax_usd from {{ source('stripe', 'payments') }} ``` การสร้าง Macro สำหรับ Logic ที่ใช้บ่อยๆ ช่วยให้มั่นใจว่าการคำนวณจะเหมือนกันทุกที่ และหากต้องการแก้ไข Logic ก็ทำได้ในที่เดียว ## การตรวจสอบ Source Freshness การตรวจสอบความสดใหม่ของข้อมูลต้นทางเป็นส่วนสำคัญในการรักษาคุณภาพของ Data Pipeline dbt รองรับการตั้งค่า Freshness Checks ใน Source Configuration: ```yaml # models/staging/stripe/_stripe__sources.yml version: 2 sources: - name: stripe database: raw schema: stripe freshness: warn_after: {count: 12, period: hour} error_after: {count: 24, period: hour} loaded_at_field: _fivetran_synced tables: - name: payments - name: customers ``` การตั้งค่านี้จะแจ้งเตือนเมื่อข้อมูลไม่ได้รับการอัพเดทเกิน 12 ชั่วโมง และจะ Error เมื่อเกิน 24 ชั่วโมง ช่วยให้ทีมสามารถตรวจจับปัญหาของ Data Pipeline ได้เร็วขึ้น ## คำถามสัมภาษณ์งาน dbt ที่พบบ่อย การเตรียมตัวสำหรับการสัมภาษณ์งานในตำแหน่ง Data Analyst ที่ต้องใช้ dbt ควรครอบคลุมคำถามดังต่อไปนี้: **1. อธิบายความแตกต่างระหว่าง `{{ ref() }}` และ `{{ source() }}`** `{{ source() }}` ใช้อ้างอิงข้อมูลดิบจากภายนอก dbt Project เช่น ตารางที่ถูก Load เข้ามาโดย Fivetran หรือ Airbyte ส่วน `{{ ref() }}` ใช้อ้างอิงโมเดลอื่นภายใน dbt Project เดียวกัน การใช้ทั้งสองอย่างถูกต้องช่วยให้ dbt สร้าง Data Lineage ได้สมบูรณ์ **2. เมื่อใดควรใช้ Incremental Model แทน Table** ควรใช้ Incremental Model เมื่อข้อมูลมีขนาดใหญ่มาก (หลายล้านแถว) และมีคอลัมน์ Timestamp ที่สามารถใช้ระบุข้อมูลใหม่ได้ เช่น Event Tables หรือ Transaction Logs อย่างไรก็ตาม ต้องระวังว่า Incremental Model มีความซับซ้อนในการจัดการมากกว่า และควรมีกลยุทธ์ในการ Full Refresh เป็นระยะ **3. อธิบายโครงสร้าง Staging-Intermediate-Marts** Staging Layer รับข้อมูลจาก Source และทำความสะอาด โดยปกติจะ Materialize เป็น View เนื่องจากมี Logic น้อยและไม่ถูก Query โดยตรง Intermediate Layer รวมข้อมูลจากหลาย Staging Models และเพิ่ม Business Logic บางส่วน Marts Layer สร้างตารางที่พร้อมใช้งานสำหรับ Business Users โดย Materialize เป็น Table เพื่อประสิทธิภาพในการ Query **4. จะจัดการกับ Late-Arriving Data ใน Incremental Model อย่างไร** สามารถใช้ Lookback Window โดยแก้ไขเงื่อนไข Incremental ให้ดึงข้อมูลย้อนหลังเพิ่มเติม เช่น ดึงข้อมูล 3 วันย้อนหลังแทนที่จะดึงเฉพาะข้อมูลใหม่กว่า Max Timestamp นอกจากนี้ควรตั้ง Full Refresh Schedule เช่น สัปดาห์ละครั้ง เพื่อแก้ปัญหาข้อมูลที่อาจตกหล่น **5. อธิบายประโยชน์ของ dbt Tests** dbt Tests ช่วยตรวจจับปัญหาคุณภาพข้อมูลก่อนที่จะส่งผลกระทบต่อ Dashboard หรือ Report ทำให้ทีมมั่นใจในความถูกต้องของข้อมูลที่ใช้ตัดสินใจ Generic Tests เหมาะสำหรับการตรวจสอบพื้นฐานเช่น Uniqueness และ Not Null ส่วน Singular Tests เหมาะสำหรับ Business Logic ที่ซับซ้อน ## แนวปฏิบัติที่ดีสำหรับ dbt ในทีม Data Analytics การนำ dbt มาใช้ในองค์กรอย่างมีประสิทธิภาพต้องอาศัยแนวปฏิบัติที่ดีดังต่อไปนี้: **การตั้งชื่อที่สอดคล้อง**: ใช้ Naming Convention ที่ชัดเจน เช่น `stg_[source]__[table]` สำหรับ Staging และ `fct_[noun]` หรือ `dim_[noun]` สำหรับ Marts การตั้งชื่อที่ดีช่วยให้ทีมเข้าใจโครงสร้างได้ทันที **การเขียน Documentation**: ทุกโมเดลและทุกคอลัมน์ที่สำคัญควรมี Description ใน YAML dbt สามารถสร้าง Documentation Website จากข้อมูลเหล่านี้โดยอัตโนมัติ **การแยก Environment**: ใช้ Target ที่แตกต่างกันสำหรับ Development และ Production เพื่อป้องกันการเปลี่ยนแปลงที่ไม่ตั้งใจกระทบข้อมูลจริง **การใช้ Version Control**: dbt Projects ควรอยู่ใน Git Repository และมีกระบวนการ Code Review ก่อน Merge เข้า Main Branch **การจัดการ Dependencies**: ใช้ `packages.yml` เพื่อจัดการ External Packages เช่น dbt-utils และกำหนด Version ที่ชัดเจนเพื่อป้องกันปัญหา Breaking Changes ## บทสรุป dbt ได้เปลี่ยนแปลงวิธีการทำงานของ Data Analyst อย่างมีนัยสำคัญ โดยนำแนวคิดจาก Software Engineering มาประยุกต์ใช้กับ Data Transformation ทักษะ dbt จึงเป็นสิ่งจำเป็นสำหรับผู้ที่ต้องการเติบโตในสายงาน Data Analytics ประเด็นสำคัญที่ควรจดจำ: - **การออกแบบโมเดลแบบ Layered** ช่วยให้โค้ดมีโครงสร้างที่ดีและบำรุงรักษาง่าย โดยแบ่งเป็น Staging, Intermediate และ Marts - **Incremental Models** ช่วยประหยัดเวลาและทรัพยากรเมื่อทำงานกับข้อมูลขนาดใหญ่ แต่ต้องออกแบบอย่างรอบคอบ - **การทดสอบข้อมูล** ทั้ง Generic และ Singular Tests ช่วยรักษาคุณภาพข้อมูลและสร้างความมั่นใจในการตัดสินใจ - **Macros** ช่วยลดการเขียนโค้ดซ้ำซ้อนและทำให้การบำรุงรักษาง่ายขึ้น - **Source Freshness** ช่วยตรวจจับปัญหาของ Data Pipeline ได้อย่างรวดเร็ว - **การเตรียมตัวสัมภาษณ์** ควรเข้าใจทั้งแนวคิดและการนำไปใช้งานจริง --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/data-analytics/dbt-data-analysts-modeling-testing-interview-2026