本专题汇集了2024年针对ETL(提取、转换、加载)开发职位的热门面试题及答案解析,旨在帮助求职者深入理解ETL技术要点与实际应用场景。
### 2024 ETL开发公司面试题解析
#### 题目一:Oracle层次查询-查询每个学生所选择的课程列表(同一行显示)
**题目解析:**
本题旨在考察考生对于Oracle中复杂查询的理解与应用能力,特别是如何处理多表连接以及如何使用窗口函数来解决实际问题。
**解决方案:**
为了实现题目需求,首先需要通过连接操作将三张表(`T_STU`, `T_COURSE`, `T_S_C`)关联起来,进而获取到学生、课程及其对应的成绩信息。接着,利用窗口函数`RANK()`对每门课程的成绩进行排名,以便根据排名构建出层次结构,最终实现将学生所选修的课程名称在一行中展示。
**步骤详解:**
1. **创建并填充表格:**
- `T_STU`: 存储学生信息。
- `T_COURSE`: 保存课程信息。
- `T_S_C`: 记录学生与课程的关系及成绩。
2. **连接表格:**
```sql
SELECT s.name AS Student,
c.coursename AS Course,
sc.course AS Score
FROM T_STU s
JOIN T_S_C sc ON s.id = sc.sid
JOIN T_COURSE c ON sc.cid = c.id;
```
3. **使用窗口函数进行排名:**
```sql
WITH RankedScores AS (
SELECT s.name AS Student,
c.coursename AS Course,
sc.course AS Score,
RANK() OVER (PARTITION BY s.id ORDER BY sc.course DESC) AS Rank
FROM T_STU s
JOIN T_S_C sc ON s.id = sc.sid
JOIN T_COURSE c ON sc.cid = c.id
)
SELECT Student,
MAX(Course) KEEP (DENSE_RANK FIRST ORDER BY Rank) AS HighestScoredCourse,
MAX(Course) KEEP (DENSE_RANK LAST ORDER BY Rank) AS LowestScoredCourse
FROM RankedScores
GROUP BY Student;
```
4. **最终输出:**
上述SQL语句将返回每个学生的最高分和最低分课程。
---
#### 题目二:拆分字段为多行
**题目解析:**
本题考察的是如何处理单个字段中包含多个值的情况,要求能够将其拆分成多行记录。
**解决方案:**
针对此类问题,可以采用SQL的字符串函数如`SUBSTR()`配合循环函数`CONNECT_BY_LEVEL`来实现字段的拆分。
**步骤详解:**
1. **定义表结构:**
```sql
CREATE TABLE TableA (Id VARCHAR2(10), ano1 VARCHAR2(100), ano2 VARCHAR2(100));
```
2. **填充示例数据:**
```sql
INSERT INTO TableA VALUES (ano1, 0755,0789,010,0112, 0731,07323);
INSERT INTO TableA VALUES (ano2, 020,021,022);
```
3. **拆分字段:**
```sql
WITH SplitData AS (
SELECT Id,
CASE WHEN LEVEL > REGEXP_COUNT(ano1, ,)+1 THEN NULL ELSE SUBSTR(ano1, INSTR(ano1, ,, 1, LEVEL-1)+1, INSTR(ano1, ,, 1, LEVEL)-INSTR(ano1, ,, 1, LEVEL-1)-1) END AS Ano
FROM TableA
CONNECT BY LEVEL <= NVL(REGEXP_COUNT(ano1, ,), 0) + 1
)
SELECT Id, Ano FROM SplitData WHERE Ano IS NOT NULL;
```
---
#### 题目三:地址拆分
**题目解析:**
本题考察如何处理字符串的分割与重组。
**解决方案:**
利用SQL中的字符串函数如`SUBSTR()`和`INSTR()`来实现地址字段的拆分,并使用`UNION ALL`将结果合并。
**步骤详解:**
1. **定义表结构:**
```sql
CREATE TABLE AddressTable (name VARCHAR2(10), address VARCHAR2(100));
```
2. **填充示例数据:**
```sql
INSERT INTO AddressTable VALUES (张三, 湖北-宜昌-五峰);
INSERT INTO AddressTable VALUES (李四, 内蒙古-呼和浩特-清水河);
INSERT INTO AddressTable VALUES (小明, 广东-深圳-宝安);
```
3. **拆分地址字段:**
```sql
SELECT name, SUBSTR(address, 1, INSTR(address, -) - 1) AS 名称, 省 AS 类型
FROM AddressTable
UNION ALL
SELECT name, SUBSTR(address, INSTR(address, -, 1)+1, INSTR(address, -, 2)-INSTR(address, -, 1