107 鐵路特考員級 資訊處理 資料處理概要 考古題詳解
第 一 題20 分
請根據以下某家銀行對於記錄及儲存資料的要求,設計關聯式資料庫結構(Relational Database Schema),並標出主鍵(Primary Key)、外來鍵(Foreign Key)及每一外來鍵所參考的主鍵:
(一) 客戶資料需記錄客戶編號、客戶姓名和地址,其中客戶編號是主鍵。
(二) 客戶的貸款資料需記錄貸款帳號和貸款金額,其中貸款帳號是主鍵。
(三) 客戶的存款資料需記錄存款帳號和存款餘額,其中存款帳號是主鍵。
(四) 需記錄哪一個客戶擁有哪一筆存款。一個客戶只能有一個存款帳號,但一個存款帳號可以由多個客戶共用。
(五) 需記錄哪一個客戶貸哪些款。一個客戶可以貸多筆款,而多個客戶可以共同貸同一筆款。
登入後即可作答並保存紀錄。
核心觀念
本題評量實體關聯模型(Entity-Relationship Model, ER Model)轉換為關聯式綱要(Relational Database Schema)的標準設計能力,涵蓋關聯式資料庫設計的核心規範:
- 實體(Entity)轉換規則:將獨立實體直接轉換為關聯表(Relation),以其識別屬性作為主鍵(Primary Key, PK)。
- 一對多()關聯轉換規則:
- 判斷基數比(Cardinality Ratio)的「一端()」與「多端()」。
- 正規化標準做法是將「一端」的主鍵,作為外來鍵(Foreign Key, FK)置入「多端」的資料表中,以滿足第一正規化(1NF)並避免資料重複。
- 多對多()關聯轉換規則:
- 關聯式架構無法直接在任一實體表中記錄多對多關係(否則會產生多值屬性,違反 1NF)。
- 必須建立獨立的關聯資料表(Associative / Bridge Relation),由兩端實體的主鍵共同構成複合主鍵(Composite Primary Key),且兩者分別為外來鍵指向各自的原實體表。
- 參考完整性限制(Referential Integrity Constraint):外來鍵的值必須在其所參考的主鍵值中存在,或者為空值(Null,若業務規則允許)。
解題方法
依題意逐項推導各實體表與關聯之設計切入點:
- 實體表定義(第 (一)、(二)、(三) 點):
- 客戶(Customer):屬性包含客戶編號、客戶姓名、地址。主鍵為「客戶編號」。
- 貸款(Loan):屬性包含貸款帳號、貸款金額。主鍵為「貸款帳號」。
- 存款(Deposit):屬性包含存款帳號、存款餘額。主鍵為「存款帳號」。
- 客戶與存款關聯分析(第 (四) 點):
- 題目條件:「一個客戶只能有一個存款帳號,但一個存款帳號可以由多個客戶共用。」
- 此關聯為存款對客戶的 關聯(一筆存款對應多個客戶;一個客戶對應一筆存款)。
- 「客戶」端為多端(),「存款」端為一端()。因此,外來鍵應設計在客戶資料表中,加入屬性「存款帳號」,並參考「存款資料表」的主鍵「存款帳號」。
- 客戶與貸款關聯分析(第 (五) 點):
- 題目條件:「一個客戶可以貸多筆款,而多個客戶可以共同貸同一筆款。」
- 此關聯為客戶對貸款的 關聯。
- 必須建立獨立的關聯資料表,命名為「客戶貸款」(或「貸戶」),其屬性包含「客戶編號」與「貸款帳號」。
- 主鍵為
(客戶編號, 貸款帳號)構成之複合主鍵;「客戶編號」為外來鍵參考客戶表,「貸款帳號」為外來鍵參考貸款表。
題目各要點分析
本題為非選擇題,以下針對題目給定之五項條件進行規格對應與落實分析:
- (一) 客戶資料:屬於獨立實體,落實為資料表
客戶,欄位包含客戶編號、客戶姓名、地址,以客戶編號為 PK。
第 二 題20 分
請根據第一題設計好的關聯式資料庫,寫 SQL 指令以得到下列的查詢結果:
(一) 統計出每一個客戶的貸款筆數與總共的貸款金額。(7 分)
(二) 找出在銀行有存款也有貸款的客戶姓名。(7 分)
(三) 列出每一個客戶的編號、姓名、存款帳號和餘額。(6 分)
登入後即可作答並保存紀錄。
核心觀念
本題評量關聯式資料庫結構化查詢語言(SQL)的核心操作能力,涵蓋關聯綱目參照、多表連接、群組聚合統計與子查詢篩選。涉及的關鍵概念如下:
- 關聯綱目假設(依據前一題設計):
- 客戶資料表
Customer(CustID, CustName, Phone, Address),主鍵為CustID。 - 存款帳戶資料表
Account(AccNo, CustID, Balance),主鍵為AccNo,外鍵為CustID(參照Customer)。 - 貸款資料表
Loan(LoanNo, CustID, Amount),主鍵為LoanNo,外鍵為CustID(參照Customer)。
- 聚合函數與分組(Aggregate Functions & GROUP BY):使用
COUNT計算筆數、SUM計算加總值,並依據非聚合欄位進行GROUP BY群組化。 - 外部連接(Outer Join)與空值處理:題目要求統計「每一個客戶」,語意上包含無貸款或無存款紀錄的客戶,須使用
LEFT OUTER JOIN確保所有客戶皆被納入,並使用COALESCE或COUNT(欄位名)妥善處理NULL值。 - 集合交集與子查詢(Intersection & Subquery):運用巢狀子查詢
IN或集合運算子INTERSECT,找出同時具備兩種關聯紀錄(有存款且有貸款)的資料列。
解題方法
(一) 統計出每一個客戶的貸款筆數與總共的貸款金額
- 切入點:因需列出「每一個客戶」,若直接使用
INNER JOIN或僅從Loan表查詢,無貸款之客戶將被遺漏。因此以Customer為主表,對Loan表進行LEFT JOIN。 - 計算處理:
- 貸款筆數:計算
COUNT(L.LoanNo)。若該客戶無貸款,L.LoanNo為NULL,計算結果為 ;若誤用COUNT(*)則會將NULL列計為 筆。 - 總貸款金額:計算
SUM(L.Amount),並使用COALESCE(SUM(L.Amount), 0)將無貸款者的NULL轉為 。 - 分組原則:
SELECT清單中的非聚合欄位(C.CustID,C.CustName)必須全數列入GROUP BY子句中。
(二) 找出在銀行有存款也有貸款的客戶姓名
- 切入點:尋找「客戶編號同時存在於
Account與Loan」的交集條件。 - 實作方式:使用
WHERE子句搭配雙重IN子查詢(或EXISTS),語意最為直觀且能自動消除重複客戶名稱,亦可避免多對多關聯連接所產生的笛卡兒積冗餘。
(三) 列出每一個客戶的編號、姓名、存款帳號和餘額
- 切入點:將
Customer與Account依客戶編號進行關聯。 - 連接選擇:題幹強調「每一個客戶」,嚴謹做法係採用
LEFT JOIN,使尚未開立存款帳號的客戶亦能列出其編號與姓名,其帳號與餘額則以NULL顯示;若僅列出已開戶者,則採用INNER JOIN。
選項分析(語法元件與替代解法剖析)
本題為非選擇題(SQL 程式設計題),各子題核心元件與替代寫法評析如下:
- 子題 (一) 語法分析:
LEFT JOINvsINNER JOIN:使用LEFT JOIN才能保證「從未貸款的客戶」也以 0 筆、金額 0 元列出,符合「每一個客戶」之嚴格語意;
第 三 題30 分
要解析一個數學運算式,一般需要用到資料結構——堆疊(Stack)。請以畫圖說明當讀入以下運算式中的每一個運算子或運算元後,堆疊中的資料儲存情況。
登入後即可作答並保存紀錄。
核心觀念
本題旨在評量堆疊(Stack)在算術運算式解析與求值(Arithmetic Expression Parsing and Evaluation)之實務應用。核心概念包含:
- 堆疊的運作特性: 堆疊為後進先出(LIFO, Last-In-First-Out)之線性資料結構,所有插入(Push)與刪除(Pop)皆在頂端(Top)進行。
- 運算子優先權(Operator Precedence)與結合性(Associativity):
- 乘除(、)之優先權高於加減(、)。
- 當讀入新運算子的優先權小於或等於堆疊頂端運算子之優先權時,堆疊頂端的運算子必須先彈出執行運算。
- 雙堆疊求值機制(Two-Stack Algorithm): 解析中序運算式(Infix Expression)一般採用兩個堆疊協同運作:
- 運算元堆疊(Operand Stack):儲存數值資料(運算元)。
- 運算子堆疊(Operator Stack):暫存運算符號,確保運算順序符合先乘除後加減。
- 當彈出二元運算子 時,運算元堆疊依序彈出兩數 (先彈出,為右運算元)與 (後彈出,為左運算元),計算 後,將結果推回運算元堆疊。
解題方法
題目運算式為:
依序讀入的符號(Token)共有 6 個:8 * 9 + 6 =。
以下繪圖詳細展示每讀入一個符號時,運算元堆疊(Operand Stack)與運算子堆疊(Operator Stack)的內部資料儲存變化:
步驟 1:讀入運算元 8
- 規則:運算元直接推入運算元堆疊。
[運算元堆疊] [運算子堆疊]
┌─────────┐ ┌─────────┐
│ 8 │<─Top │ (空) │
└─────────┘ └─────────┘
步驟 2:讀入運算子 *
- 規則:運算子堆疊為空,直接將
*推入運算子堆疊。
[運算元堆疊] [運算子堆疊]
┌─────────┐ ┌─────────┐
│ 8 │<─Top │ * │<─Top
└─────────┘ └─────────┘
步驟 3:讀入運算元 9
- 規則:運算元直接推入運算元堆疊。
[運算元堆疊] [運算子堆疊]
┌─────────┐ ┌─────────┐
│ 9 │<─Top │ * │<─Top
├─────────┤ └─────────┘
│ 8 │
└─────────┘
步驟 4:讀入運算子 +
- 規則:
- 比較優先權:讀入的
+優先權低於堆疊頂端的*。 - 彈出運算子
*,並由運算元堆疊彈出右運算元9與左運算元8。 - 計算 ,將運算結果
72推回運算元堆疊。 - 此時運算子堆疊已空,將
+推入運算子堆疊。
第 四 題30 分
合併排序法(Merge Sort)是排序演算法的一種,使用分治(Divide and Conquer)的方法來實作。假設我們有 筆資料如下:
請畫圖說明合併排序法的運作過程。
登入後即可作答並保存紀錄。
核心觀念
合併排序法(Merge Sort)是典型的分治法(Divide and Conquer)演算法,其核心思想包含三個主要步驟:
- 分割(Divide):將待排序的 筆資料從中間切分為兩半,遞迴地將每個子數列繼續對分,直到每個子數列的長度為 。
- 解決(Conquer):當子數列長度為 時,視為天然已排序狀態(遞迴終止條件,Base Case)。
- 結合/合併(Combine / Merge):依序由底向上將兩個已排序的相鄰子數列,透過雙指針(Two Pointers)線性比對元素大小,合併為一個較大的有序數列,直至還原為長度為 的完整已排序數列。
重要性質與評分要點:
- 時間複雜度:最差、最佳、平均皆為 。其遞迴關係式為 ,樹狀高度為 。
- 空間複雜度:(非原地排序 Out-of-place,合併時需要額外的暫存陣列)。
- 穩定性(Stability):屬於穩定排序(Stable Sort)。題目中有兩筆鍵值相同的資料(),在合併過程中,若兩端數值相等,應優先取出左側子數列的元素,以維持其原始相對位置。
解題方法
給定 筆資料,為凸顯穩定排序特性,將兩筆數值為 的資料分別標記為 與 :
解題分為兩大階段推導並繪製架構圖:
1. 分割階段(Divide)
- Level 0(原始資料,長度 8):
- Level 1(對半切分,長度各 4):
- 左半部:
- 右半部:
- Level 2(再度切分,長度各 2):
- 、、、
- Level 3(切分至基本單位,長度各 1):
- 、、、、、、、
2. 合併階段(Merge)
- 第一次合併(長度 ):
- 與 合併
- 與 合併
- 與 合併
- 與 合併
- 第二次合併(長度 ):
- 與 合併:比對首項元素依次取出 ,得
- 與 合併:比對首項元素依次取出 ,得
- 第三次合併(長度 ,完成排序):
- 比對 與 :
- 比較 與 取出
- 比較 與 取出
- 比較 與 取出
- 比較 與 因左側優先(穩定性),取出
- 比較 與 取出