【Oracle】视图

在这里插入图片描述

个人主页:Guiat
归属专栏:Oracle

在这里插入图片描述

文章目录

  • 1. 视图基础概述
    • 1.1 视图的概念与特点
    • 1.2 视图的工作原理
    • 1.3 视图的分类
  • 2. 简单视图
    • 2.1 创建简单视图
      • 2.1.1 基本简单视图
      • 2.1.2 带计算列的简单视图
    • 2.2 简单视图的DML操作
      • 2.2.1 通过视图进行INSERT操作
      • 2.2.2 通过视图进行UPDATE操作
      • 2.2.3 通过视图进行DELETE操作
  • 3. 复杂视图
    • 3.1 多表连接视图
      • 3.1.1 员工部门视图
      • 3.1.2 员工层级关系视图
    • 3.2 聚合统计视图
      • 3.2.1 部门统计视图
      • 3.2.2 职位薪资分析视图
    • 3.3 时间序列分析视图
      • 3.3.1 年度招聘趋势视图
  • 4. 视图的更新控制
    • 4.1 WITH CHECK OPTION
      • 4.1.1 基本CHECK OPTION
      • 4.1.2 分级CHECK OPTION
    • 4.2 WITH READ ONLY
  • 5. 物化视图
    • 5.1 基本物化视图
      • 5.1.1 创建物化视图
      • 5.1.2 自动刷新物化视图
    • 5.2 快速刷新物化视图
      • 5.2.1 创建物化视图日志
      • 5.2.2 创建快速刷新物化视图
  • 6. 视图管理与维护
    • 6.1 查看视图信息
      • 6.1.1 视图元数据查询
      • 6.1.2 物化视图状态查询
    • 6.2 视图性能优化
      • 6.2.1 执行计划分析
      • 6.2.2 视图性能优化建议
    • 6.3 视图的修改和删除
      • 6.3.1 修改视图
      • 6.3.2 删除视图
  • 7. 视图安全与权限
    • 7.1 视图权限管理
      • 7.1.1 授予视图权限
      • 7.1.2 回收视图权限
    • 7.2 行级安全(RLS)视图
      • 7.2.1 创建安全视图
    • 7.3 视图最佳实践
      • 7.3.1 命名规范
      • 7.3.2 设计原则
  • 8. 实际应用案例
    • 8.1 企业报表视图系统
      • 8.1.1 销售业绩报表视图
      • 8.1.2 客户分析视图
    • 8.2 数据仓库视图层
      • 8.2.1 维度视图
      • 8.2.2 事实视图

正文

1. 视图基础概述

视图是Oracle数据库中的虚拟表,它是基于一个或多个表的查询结果集。视图不存储实际数据,而是存储查询定义,当访问视图时动态执行查询。

1.1 视图的概念与特点

Oracle视图
虚拟表
查询定义
数据安全
简化复杂查询
不存储实际数据
动态生成结果
基于SELECT语句
可包含多表连接
隐藏敏感列
行级安全控制
封装复杂逻辑
提供统一接口

1.2 视图的工作原理

用户查询视图
Oracle解析视图定义
合并查询条件
执行底层表查询
返回结果集
视图定义
基础表

1.3 视图的分类

Oracle视图类型
简单视图
复杂视图
物化视图
内联视图
可更新视图
基于单表
无聚合函数
支持DML操作
多表连接
包含函数/分组
只读视图
存储查询结果
定期刷新
提高查询性能
查询中的子查询
临时视图
WITH CHECK OPTION
WITH READ ONLY

2. 简单视图

简单视图基于单个表,通常可以进行DML操作。

2.1 创建简单视图

2.1.1 基本简单视图

-- 创建基本的简单视图
CREATE VIEW emp_basic_info AS
SELECT employee_id, first_name, last_name, email, hire_date
FROM employees;-- 创建带WHERE条件的简单视图
CREATE VIEW active_employees AS
SELECT employee_id, first_name, last_name, email, phone_number, hire_date, salary
FROM employees
WHERE hire_date >= DATE '2020-01-01';-- 创建带列别名的简单视图
CREATE VIEW emp_summary AS
SELECT employee_id AS emp_id,first_name || ' ' || last_name AS full_name,email AS email_address,salary AS monthly_salary,salary * 12 AS annual_salary,hire_date
FROM employees;-- 查看视图结构
DESCRIBE emp_basic_info;-- 查询视图数据
SELECT * FROM emp_basic_info WHERE employee_id < 110;

2.1.2 带计算列的简单视图

-- 创建包含计算列的视图
CREATE VIEW emp_salary_analysis AS
SELECT employee_id,first_name || ' ' || last_name AS employee_name,salary,salary * 12 AS annual_salary,CASE WHEN salary < 5000 THEN 'Low'WHEN salary BETWEEN 5000 AND 10000 THEN 'Medium'WHEN salary > 10000 THEN 'High'END AS salary_grade,ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) AS months_employed,ROUND(MONTHS_BETWEEN(SYSDATE, hire_date) / 12, 1) AS years_employed
FROM employees;-- 查询计算列视图
SELECT employee_name, salary_grade, annual_salary, years_employed
FROM emp_salary_analysis
WHERE salary_grade = 'High'
ORDER BY annual_salary DESC;

2.2 简单视图的DML操作

2.2.1 通过视图进行INSERT操作

-- 创建可插入的视图
CREATE VIEW emp_insert_view AS
SELECT employee_id, first_name, last_name, email, hire_date, job_id, department_id
FROM employees;-- 通过视图插入数据
INSERT INTO emp_insert_view (employee_id, first_name, last_name, email, hire_date, job_id, department_id
) VALUES (999, 'John', 'Doe', 'john.doe@company.com', SYSDATE, 'IT_PROG', 60
);-- 验证插入结果
SELECT * FROM emp_insert_view WHERE employee_id = 999;
SELECT * FROM employees WHERE employee_id = 999;

2.2.2 通过视图进行UPDATE操作

-- 通过视图更新数据
UPDATE emp_insert_view 
SET email = 'john.doe.updated@company.com',job_id = 'IT_ADMIN'
WHERE employee_id = 999;-- 批量更新
UPDATE emp_salary_analysis 
SET salary = salary * 1.05
WHERE salary_grade = 'Low';-- 验证更新结果
SELECT employee_id, employee_name, salary, salary_grade
FROM emp_salary_analysis
WHERE employee_id = 999;

2.2.3 通过视图进行DELETE操作

-- 通过视图删除数据
DELETE FROM emp_insert_view WHERE employee_id = 999;-- 验证删除结果
SELECT COUNT(*) FROM employees WHERE employee_id = 999;

3. 复杂视图

复杂视图基于多个表或包含函数、分组等复杂操作,通常是只读的。

3.1 多表连接视图

3.1.1 员工部门视图

-- 创建员工部门完整信息视图
CREATE VIEW emp_dept_detail AS
SELECT e.employee_id,e.first_name || ' ' || e.last_name AS employee_name,e.email,e.salary,e.hire_date,j.job_title,d.department_name,d.manager_id AS dept_manager_id,dm.first_name || ' ' || dm.last_name AS dept_manager_name,l.city,l.state_province,c.country_name
FROM employees e
JOIN jobs j ON e.job_id = j.job_id
JOIN departments d ON e.department_id = d.department_id
LEFT JOIN employees dm ON d.manager_id = dm.employee_id
JOIN locations l ON d.location_id = l.location_id
JOIN countries c ON l.country_id = c.country_id;-- 查询员工部门详细信息
SELECT employee_name, job_title, department_name, city, country_name
FROM emp_dept_detail
WHERE country_name = 'United States'
ORDER BY department_name, employee_name;

3.1.2 员工层级关系视图

-- 创建员工管理层级视图
CREATE VIEW emp_hierarchy AS
SELECT e.employee_id,e.first_name || ' ' || e.last_name AS employee_name,e.job_id,e.salary,e.hire_date,e.manager_id,m.first_name || ' ' || m.last_name AS manager_name,m.job_id AS manager_job_id,d.department_name,LEVEL AS hierarchy_level,SYS_CONNECT_BY_PATH(e.first_name || ' ' || e.last_name, ' -> ') AS hierarchy_path
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id
JOIN departments d ON e.department_id = d.department_id
START WITH e.manager_id IS NULL
CONNECT BY PRIOR e.employee_id = e.manager_id;-- 查询组织层级结构
SELECT LPAD(' ', (hierarchy_level - 1) * 2) || employee_name AS org_structure,job_id,manager_name,department_name
FROM emp_hierarchy
WHERE department_name = 'Executive'
ORDER BY hierarchy_level, employee_name;

3.2 聚合统计视图

3.2.1 部门统计视图

-- 创建部门统计汇总视图
CREATE VIEW dept_statistics AS
SELECT d.department_id,d.department_name,d.location_id,l.city,COUNT(e.employee_id) AS employee_count,ROUND(AVG(e.salary), 2) AS avg_salary,MIN(e.salary) AS min_salary,MAX(e.salary) AS max_salary,SUM(e.salary) AS total_salary,ROUND(STDDEV(e.salary), 2) AS salary_stddev,MIN(e.hire_date) AS earliest_hire_date,MAX(e.hire_date) AS latest_hire_date
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
LEFT JOIN locations l ON d.location_id = l.location_id
GROUP BY d.department_id, d.department_name, d.location_id, l.city;-- 查询部门统计信息
SELECT department_name, employee_count,avg_salary,total_salary,city
FROM dept_statistics
WHERE employee_count > 0
ORDER BY avg_salary DESC;

3.2.2 职位薪资分析视图

-- 创建职位薪资分析视图
CREATE VIEW job_salary_analysis AS
SELECT j.job_id,j.job_title,COUNT(e.employee_id) AS position_count,ROUND(AVG(e.salary), 2) AS avg_salary,ROUND(MEDIAN(e.salary), 2) AS median_salary,MIN(e.salary) AS min_salary,MAX(e.salary) AS max_salary,j.min_salary AS job_min_salary,j.max_salary AS job_max_salary,ROUND(AVG(e.salary) - j.min_salary, 2) AS avg_above_min,ROUND(j.max_salary - AVG(e.salary), 2) AS avg_below_max,ROUND((AVG(e.salary) - j.min_salary) / (j.max_salary - j.min_salary) * 100, 1) AS salary_position_pct
FROM jobs j
LEFT JOIN employees e ON j.job_id = e.job_id
GROUP BY j.job_id, j.job_title, j.min_salary, j.max_salary;-- 查询职位薪资分析
SELECT job_title,position_count,avg_salary,median_salary,salary_position_pct || '%' AS position_in_range
FROM job_salary_analysis
WHERE position_count > 0
ORDER BY avg_salary DESC;

3.3 时间序列分析视图

3.3.1 年度招聘趋势视图

-- 创建年度招聘趋势分析视图
CREATE VIEW yearly_hiring_trends AS
SELECT hire_year,total_hired,LAG(total_hired, 1) OVER (ORDER BY hire_year) AS prev_year_hired,total_hired - LAG(total_hired, 1) OVER (ORDER BY hire_year) AS year_over_year_change,ROUND((total_hired - LAG(total_hired, 1) OVER (ORDER BY hire_year)) / LAG(total_hired, 1) OVER (ORDER BY hire_year) * 100, 1) AS yoy_change_pct,avg_starting_salary,LAG(avg_starting_salary, 1) OVER (ORDER BY hire_year) AS prev_avg_salary,ROUND(avg_starting_salary - LAG(avg_starting_salary, 1) OVER (ORDER BY hire_year), 2) AS salary_change
FROM (SELECT EXTRACT(YEAR FROM hire_date) AS hire_year,COUNT(*) AS total_hired,ROUND(AVG(salary), 2) AS avg_starting_salaryFROM employeesGROUP BY EXTRACT(YEAR FROM hire_date)
);-- 查询招聘趋势
SELECT hire_year,total_hired,CASE WHEN yoy_change_pct > 0 THEN '+' || yoy_change_pct || '%'WHEN yoy_change_pct < 0 THEN yoy_change_pct || '%'ELSE 'N/A'END AS growth_rate,avg_starting_salary,salary_change
FROM yearly_hiring_trends
ORDER BY hire_year;

4. 视图的更新控制

4.1 WITH CHECK OPTION

WITH CHECK OPTION确保通过视图进行的DML操作符合视图的WHERE条件。

4.1.1 基本CHECK OPTION

-- 创建带CHECK OPTION的视图
CREATE VIEW high_salary_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM employees
WHERE salary > 8000
WITH CHECK OPTION;-- 尝试插入符合条件的记录(成功)
INSERT INTO high_salary_employees 
VALUES (998, 'Jane', 'Smith', 9000, 60);-- 尝试插入不符合条件的记录(失败)
-- 以下操作会产生错误:ORA-01402: view WITH CHECK OPTION where-clause violation
BEGININSERT INTO high_salary_employees VALUES (997, 'Bob', 'Johnson', 5000, 60);
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('错误: ' || SQLERRM);
END;
/-- 尝试更新为不符合条件的值(失败)
BEGINUPDATE high_salary_employees SET salary = 3000 WHERE employee_id = 998;
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('更新错误: ' || SQLERRM);
END;
/

4.1.2 分级CHECK OPTION

-- 创建基础视图
CREATE VIEW dept_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM employees
WHERE department_id = 60;-- 创建基于视图的视图,带CHECK OPTION
CREATE VIEW senior_dept_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM dept_employees
WHERE salary > 7000
WITH CHECK OPTION;-- 测试分级检查
INSERT INTO senior_dept_employees 
VALUES (996, 'Alice', 'Brown', 8500, 60); -- 成功-- 清理测试数据
DELETE FROM employees WHERE employee_id IN (996, 998);

4.2 WITH READ ONLY

WITH READ ONLY选项创建只读视图,禁止任何DML操作。

-- 创建只读视图
CREATE VIEW emp_salary_report AS
SELECT d.department_name,e.employee_id,e.first_name || ' ' || e.last_name AS employee_name,e.salary,e.hire_date,RANK() OVER (PARTITION BY d.department_id ORDER BY e.salary DESC) AS salary_rank
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WITH READ ONLY;-- 查询只读视图
SELECT department_name, employee_name, salary, salary_rank
FROM emp_salary_report
WHERE salary_rank <= 3
ORDER BY department_name, salary_rank;-- 尝试更新只读视图(会失败)
BEGINUPDATE emp_salary_report SET salary = 10000 WHERE employee_id = 100;
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('只读视图错误: ' || SQLERRM);
END;
/

5. 物化视图

物化视图是将查询结果物理存储的视图,可以显著提高复杂查询的性能。

5.1 基本物化视图

5.1.1 创建物化视图

-- 创建基本物化视图
CREATE MATERIALIZED VIEW mv_dept_summary
BUILD IMMEDIATE
REFRESH COMPLETE ON DEMAND
AS
SELECT d.department_id,d.department_name,COUNT(e.employee_id) AS emp_count,ROUND(AVG(e.salary), 2) AS avg_salary,SUM(e.salary) AS total_salary
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_id, d.department_name;-- 查询物化视图
SELECT * FROM mv_dept_summary 
WHERE emp_count > 0 
ORDER BY avg_salary DESC;-- 手动刷新物化视图
EXEC DBMS_MVIEW.REFRESH('mv_dept_summary');

5.1.2 自动刷新物化视图

-- 创建自动刷新的物化视图
CREATE MATERIALIZED VIEW mv_monthly_stats
BUILD IMMEDIATE
REFRESH COMPLETE ON COMMIT
AS
SELECT EXTRACT(YEAR FROM hire_date) AS hire_year,EXTRACT(MONTH FROM hire_date) AS hire_month,COUNT(*) AS employees_hired,ROUND(AVG(salary), 2) AS avg_starting_salary
FROM employees
GROUP BY EXTRACT(YEAR FROM hire_date), EXTRACT(MONTH FROM hire_date);-- 当基础表发生变化时,物化视图会自动刷新
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary, department_id)
VALUES (995, 'Test', 'Employee', 'test@company.com', SYSDATE, 'IT_PROG', 6000, 60);COMMIT;-- 查看更新后的物化视图
SELECT * FROM mv_monthly_stats 
WHERE hire_year = EXTRACT(YEAR FROM SYSDATE)
ORDER BY hire_year, hire_month;-- 清理测试数据
DELETE FROM employees WHERE employee_id = 995;
COMMIT;

5.2 快速刷新物化视图

快速刷新只更新发生变化的部分,需要物化视图日志。

5.2.1 创建物化视图日志

-- 为基础表创建物化视图日志
CREATE MATERIALIZED VIEW LOG ON employees
WITH ROWID, SEQUENCE (employee_id, department_id, salary)
INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW LOG ON departments
WITH ROWID, SEQUENCE (department_id, department_name)
INCLUDING NEW VALUES;

5.2.2 创建快速刷新物化视图

-- 创建支持快速刷新的物化视图
CREATE MATERIALIZED VIEW mv_dept_summary_fast
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
AS
SELECT d.department_id,d.department_name,COUNT(e.employee_id) AS emp_count,SUM(e.salary) AS total_salary,COUNT(*) AS row_count
FROM departments d, employees e
WHERE d.department_id = e.department_id(+)
GROUP BY d.department_id, d.department_name;-- 进行一些更改
UPDATE employees SET salary = salary + 100 WHERE employee_id = 100;-- 快速刷新物化视图
EXEC DBMS_MVIEW.REFRESH('mv_dept_summary_fast', 'F');-- 查看刷新后的结果
SELECT * FROM mv_dept_summary_fast ORDER BY department_id;

6. 视图管理与维护

6.1 查看视图信息

6.1.1 视图元数据查询

-- 查看用户拥有的所有视图
SELECT view_name, text_length, read_only
FROM user_views
ORDER BY view_name;-- 查看视图的详细定义
SELECT view_name, text
FROM user_views
WHERE view_name = 'EMP_DEPT_DETAIL';-- 查看视图的列信息
SELECT column_name, data_type, nullable
FROM user_tab_columns
WHERE table_name = 'EMP_DEPT_DETAIL'
ORDER BY column_id;-- 查看视图的依赖关系
SELECT name, type, referenced_name, referenced_type
FROM user_dependencies
WHERE name = 'EMP_DEPT_DETAIL';

6.1.2 物化视图状态查询

-- 查看物化视图信息
SELECT mview_name, refresh_mode, refresh_method, build_mode, last_refresh_date, compile_state
FROM user_mviews;-- 查看物化视图刷新历史
SELECT mview_name, refresh_method, start_time, end_time, elapsed_time
FROM user_mview_refresh_times
WHERE mview_name = 'MV_DEPT_SUMMARY'
ORDER BY start_time DESC;-- 查看物化视图日志信息
SELECT log_table, master, log_trigger, rowids, primary_key, object_id
FROM user_mview_logs;

6.2 视图性能优化

6.2.1 执行计划分析

-- 分析视图查询的执行计划
EXPLAIN PLAN FOR
SELECT employee_name, department_name, salary
FROM emp_dept_detail
WHERE salary > 8000
ORDER BY salary DESC;SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);-- 比较直接查询和视图查询的性能
EXPLAIN PLAN FOR
SELECT e.first_name || ' ' || e.last_name AS employee_name,d.department_name,e.salary
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 8000
ORDER BY e.salary DESC;SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

6.2.2 视图性能优化建议

-- 创建优化的视图,包含提示
CREATE OR REPLACE VIEW emp_dept_optimized AS
SELECT /*+ USE_NL(e d) INDEX(e emp_department_ix) */e.employee_id,e.first_name || ' ' || e.last_name AS employee_name,e.salary,d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;-- 为经常查询的列创建索引
CREATE INDEX emp_salary_idx ON employees(salary);
CREATE INDEX emp_dept_idx ON employees(department_id);

6.3 视图的修改和删除

6.3.1 修改视图

-- 使用OR REPLACE修改视图定义
CREATE OR REPLACE VIEW emp_basic_info AS
SELECT employee_id, first_name, last_name, email, hire_date,salary,  -- 新增列department_id  -- 新增列
FROM employees
WHERE hire_date >= DATE '2010-01-01';  -- 新增条件-- 验证视图修改
DESCRIBE emp_basic_info;
SELECT * FROM emp_basic_info WHERE rownum <= 5;

6.3.2 删除视图

-- 删除普通视图
DROP VIEW emp_summary;-- 删除物化视图
DROP MATERIALIZED VIEW mv_dept_summary;-- 删除物化视图日志
DROP MATERIALIZED VIEW LOG ON employees;
DROP MATERIALIZED VIEW LOG ON departments;-- 验证删除结果
SELECT view_name FROM user_views WHERE view_name IN ('EMP_SUMMARY');
SELECT mview_name FROM user_mviews WHERE mview_name = 'MV_DEPT_SUMMARY';

7. 视图安全与权限

7.1 视图权限管理

7.1.1 授予视图权限

-- 创建用于演示的视图
CREATE VIEW public_emp_info AS
SELECT employee_id, first_name, last_name, email, hire_date
FROM employees;-- 授予其他用户查询权限
GRANT SELECT ON public_emp_info TO other_user;-- 授予更新权限
GRANT UPDATE ON public_emp_info TO other_user;-- 授予所有权限
GRANT ALL ON public_emp_info TO privileged_user;-- 查看授予的权限
SELECT grantee, privilege, grantable
FROM user_tab_privs
WHERE table_name = 'PUBLIC_EMP_INFO';

7.1.2 回收视图权限

-- 回收特定权限
REVOKE UPDATE ON public_emp_info FROM other_user;-- 回收所有权限
REVOKE ALL ON public_emp_info FROM other_user;

7.2 行级安全(RLS)视图

7.2.1 创建安全视图

-- 创建部门级安全视图
CREATE VIEW secure_emp_view AS
SELECT employee_id, first_name, last_name, email, salary, department_id
FROM employees
WHERE department_id IN (SELECT department_id FROM user_dept_access WHERE username = USER
);-- 创建基于角色的视图
CREATE VIEW role_based_emp_view AS
SELECT employee_id, first_name, last_name, email,CASE WHEN USER IN (SELECT username FROM hr_managers) THEN salaryELSE NULLEND AS salary,department_id
FROM employees;

7.3 视图最佳实践

7.3.1 命名规范

-- 推荐的视图命名规范
CREATE VIEW v_employee_summary AS ...;     -- 前缀 v_
CREATE VIEW emp_dept_vw AS ...;             -- 后缀 _vw
CREATE MATERIALIZED VIEW mv_sales_summary AS ...;  -- 物化视图前缀 mv_-- 业务相关的命名
CREATE VIEW finance_employee_view AS ...;   -- 财务部门员工视图
CREATE VIEW active_projects_view AS ...;    -- 活跃项目视图

7.3.2 设计原则

视图设计最佳实践
性能考虑
安全性
维护性
可用性
避免复杂嵌套
适当使用物化视图
优化查询条件
最小权限原则
隐藏敏感数据
行级安全控制
清晰的命名规范
完整的文档
定期检查依赖
简化复杂查询
提供业务视角
标准化数据访问

8. 实际应用案例

8.1 企业报表视图系统

8.1.1 销售业绩报表视图

-- 创建销售业绩综合报表视图
CREATE VIEW sales_performance_report AS
SELECT s.salesperson_id,e.first_name || ' ' || e.last_name AS salesperson_name,d.department_name,EXTRACT(YEAR FROM s.sale_date) AS sale_year,EXTRACT(QUARTER FROM s.sale_date) AS sale_quarter,COUNT(s.sale_id) AS total_sales,SUM(s.amount) AS total_revenue,ROUND(AVG(s.amount), 2) AS avg_sale_amount,RANK() OVER (PARTITION BY EXTRACT(YEAR FROM s.sale_date), EXTRACT(QUARTER FROM s.sale_date)ORDER BY SUM(s.amount) DESC) AS performance_rank
FROM sales s
JOIN employees e ON s.salesperson_id = e.employee_id
JOIN departments d ON e.department_id = d.department_id
GROUP BY s.salesperson_id, e.first_name, e.last_name, d.department_name,EXTRACT(YEAR FROM s.sale_date), EXTRACT(QUARTER FROM s.sale_date);

8.1.2 客户分析视图

-- 创建客户价值分析视图
CREATE VIEW customer_value_analysis AS
SELECT c.customer_id,c.customer_name,c.registration_date,COUNT(o.order_id) AS total_orders,SUM(o.order_amount) AS total_spent,ROUND(AVG(o.order_amount), 2) AS avg_order_value,MAX(o.order_date) AS last_order_date,ROUND(MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)), 1) AS months_since_last_order,CASE WHEN SUM(o.order_amount) > 10000 THEN 'VIP'WHEN SUM(o.order_amount) > 5000 THEN 'Premium'WHEN SUM(o.order_amount) > 1000 THEN 'Regular'ELSE 'Basic'END AS customer_tier,CASE WHEN MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)) <= 3 THEN 'Active'WHEN MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)) <= 12 THEN 'At Risk'ELSE 'Inactive'END AS customer_status
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.customer_name, c.registration_date;

8.2 数据仓库视图层

8.2.1 维度视图

-- 时间维度视图
CREATE VIEW dim_time AS
SELECT DISTINCTTRUNC(date_column) AS date_key,EXTRACT(YEAR FROM date_column) AS year,EXTRACT(QUARTER FROM date_column) AS quarter,EXTRACT(MONTH FROM date_column) AS month,EXTRACT(DAY FROM date_column) AS day,TO_CHAR(date_column, 'Day') AS day_name,TO_CHAR(date_column, 'Month') AS month_name,CASE WHEN TO_CHAR(date_column, 'D') IN ('1', '7') THEN 'Y' ELSE 'N' END AS is_weekend
FROM (SELECT hire_date AS date_column FROM employeesUNIONSELECT order_date FROM orders
);-- 产品维度视图
CREATE VIEW dim_product AS
SELECT p.product_id,p.product_name,p.product_code,c.category_name,c.category_id,p.unit_price,p.cost_price,p.unit_price - p.cost_price AS profit_margin,CASE WHEN p.unit_price - p.cost_price > 100 THEN 'High Margin'WHEN p.unit_price - p.cost_price > 50 THEN 'Medium Margin'ELSE 'Low Margin'END AS margin_category
FROM products p
JOIN categories c ON p.category_id = c.category_id;

8.2.2 事实视图

-- 销售事实视图
CREATE VIEW fact_sales AS
SELECT s.sale_id,s.sale_date,s.customer_id,s.product_id,s.salesperson_id,s.quantity,s.unit_price,s.total_amount,s.discount_amount,s.total_amount - s.discount_amount AS net_amount,p.cost_price * s.quantity AS total_cost,(s.total_amount - s.discount_amount) - (p.cost_price * s.quantity) AS profit
FROM sales s
JOIN products p ON s.product_id = p.product_id;

通过这个全面的Oracle视图教程,我们涵盖了从基础概念到高级应用的所有重要方面。视图是Oracle数据库中非常强大的工具,正确使用可以显著提高数据安全性、查询效率和系统维护性。在实际应用中,应该根据具体需求选择合适的视图类型,并遵循最佳实践来设计和维护视图。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lua和JS的垃圾回收机制

Lua 和 JavaScript 都采用了 自动垃圾回收机制&#xff08;GC&#xff09; 来管理内存&#xff0c;开发者无需手动释放内存&#xff0c;但它们的 实现机制和行为策略不同。下面我们从原理、策略、优缺点等方面来详细对比&#xff1a; &#x1f536; 1. 基本原理对比 特性LuaJa…

Kafka 的优势是什么?

Kafka 作为分布式流处理平台的核心组件&#xff0c;其设计哲学围绕高吞吐、低延迟、高可扩展性展开&#xff0c;在实时数据管道和大数据生态中具有不可替代的地位。 一、超高吞吐量与低延迟 1. 磁盘顺序 I/O 优化 突破磁盘瓶颈&#xff1a;Kafka 将消息持久化到磁盘&#xff…

车载诊断架构 --- DTC消抖参数(Trip Counter DTCConfirmLimit )

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

【C++】类的析构函数

类的析构函数 1. 作用&#xff1a;1.1 当对象的地址空间释放的时候&#xff0c;会自动调用析构函数(对象可以主动调用析构函数)1.2 实际应用&#xff1a;往往用来做收尾工作 2. 语法规则&#xff1a;示例代码&#xff1a;析构函数使用 1. 作用&#xff1a; 1.1 当对象的地址空…

重拾Scrapy框架

基于Scrapy框架实现 舔狗语录百度翻译 输出结果到txt文档 爬虫脚本 from typing import Iterable, Any, AsyncIteratorimport scrapy import json from post.items import PostItemclass BaidufanyiSpider(scrapy.Spider):name "baidufanyi"allowed_domains [&quo…

【实例】事业单位学习平台自动化操作

目录 一、创作背景: 二、实现逻辑: 三、代码分析【Deepseek分析】: 1) 主要功能 2)核心组件 2.1 GUI界面 (AutomationApp类) 2.2 浏览器自动化 2.3 平台特定处理 3) 关键技术 4)代码亮点 5)总结 四、运行截图: 五、程序代码: 特别声明:***本代码仅限编程学…

CSS篇-1

1. CSS 有哪些基本选择器?它们的权重是如何表示的? 这是一个关于 CSS 基础且极其重要的问题,因为它直接关系到我们如何精准地控制页面元素的样式,以及在样式冲突时浏览器如何决定哪个样式生效。理解 CSS 选择器及其权重(或称为“优先级”或“特殊性”),是编写高效、可维…

封装一个Qt调用动态库的类

封装一个Qt调用动态库的类 由于我的操作系统Ubuntu系统,我就以Linux下的动态库.so为例了,其实windows上的dll库调用方式是一样的,如果你的Qt项目是windows的,这篇文章代码可以直接使用。 一般情况下我们对外输出都是以动态库的形式封装的,这样我们更新版本的时候就很方便…

阴盘奇门 api数据接口

阴盘奇门&#xff0c;又称"道家阴盘遁甲"或"法术奇门"&#xff0c;与阳盘奇门(奇门排盘)并称"奇门双雄"。由王凤麟教授整合道家三式&#xff08;奇门、六壬、太乙&#xff09;精髓创立&#xff0c;独创行为风水与立体全息预测技术&#xff0c;广…

【计算机网络】第3章:传输层—可靠数据传输的原理

目录 一、PPT 二、总结 &#xff08;一&#xff09;可靠数据传输原理 关键机制 1. 序号机制 (Sequence Numbers) 2. 确认机制 (Acknowledgements - ACKs) 3. 重传机制 (Retransmission) 4. 校验和 (Checksum) 5. 流量控制 (Flow Control) 协议实现的核心&#xff1a;滑…

C#实现图片缩略图生成:多种模式详解与实践

C#实现图片缩略图生成&#xff1a;多种模式详解与实践 在图像处理的场景中&#xff0c;生成图片缩略图是一项常见且实用的功能。无论是搭建图片展示网站&#xff0c;还是开发本地图片管理工具&#xff0c;按需生成合适尺寸的缩略图&#xff0c;能够有效减少图片传输和显示所需…

2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版

1.题目描述 2.思路 3.代码实现 import java.util.LinkedList; import java.util.Queue;public class H994 {public int orangesRotting(int[][] grid) {//1.获取行数int rowsgrid.length;int colsgrid[0].length;//2.创建队列用于bfsQueue<int[]> quenew LinkedList<…

005 flutter基础,初始文件讲解(4)

书接上回&#xff0c;今天继续完成最后的讲解&#xff1a; class _MyHomePageState extends State<MyHomePage> {int _counter 0;void _incrementCounter() {setState(() {_counter;});}可以看到&#xff0c;这里的_MyHomePageState是一个类&#xff0c;继承于 State&l…

DeepSeek R1开源模型的技术突破与AI产业格局的重构

引言​ 2025年&#xff0c;中国AI企业深度求索&#xff08;DeepSeek&#xff09;推出的开源模型DeepSeek-R1&#xff0c;以低成本、高性能和开放生态为核心特征&#xff0c;成为全球人工智能领域的技术焦点。这一模型不仅通过算法创新显著降低算力依赖&#xff0c;更通过开源策…

轻量级swiper插件推荐

推荐插件列表&#xff08;按体积从小到大排序&#xff09; 1. Embla Carousel 体积&#xff1a;约 5KB (gzipped) 官网&#xff1a;A lightweight carousel library with fluid motion and great swipe precision | Embla Carousel 特点&#xff1a; 极小体积&#xff0c;高…

设计模式——访问者设计模式(行为型)

摘要 访问者设计模式是一种行为型设计模式&#xff0c;它将数据结构与作用于结构上的操作解耦&#xff0c;允许在不修改数据结构的前提下增加新的操作行为。该模式包含关键角色如元素接口、具体元素类、访问者接口和具体访问者类。通过访问者模式&#xff0c;可以在不改变对象…

Vue基础(12)_Vue.js循环语句用法:列表渲染

js补充 术语解释 循环(loop)&#xff1a;最基础的概念, 所有重复的行为。 递归(recursion)&#xff1a; 在函数内调用自身, 将复杂情况逐步转化成基本情况。 (数学)迭代(iterate) &#xff1a;在多次循环中逐步接近结果。 (编程)迭代(iterate) &#xff1a;按顺序访问线性结构中…

Linux入门(十三)动态监控系统监控网络状态

top与ps 命令很相似&#xff0c;它们都是用来显示正在执行的进程&#xff0c;top与ps大的区别是top在执行一段时间可以更新正在运行的进程。 #-d 更新秒数 如果不写-d 那默认是3秒更新 # -i 隐藏不活跃进程 top -d 5交互操作 P 按cpu使用大小排序&#xff0c;默认此项 M 按内存…

Java 中 MySQL 索引深度解析:面试核心知识点与实战

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Java 中 MySQL 索引深度解析&#xff1a;面试…

Kafka集成Flume/Spark/Flink(大数据)/SpringBoot

Kafka集成Flume Flume生产者 ③、安装Flume&#xff0c;上传apache-flume的压缩包.tar.gz到Linux系统的software&#xff0c;并解压到/opt/module目录下&#xff0c;并修改其名称为flume Flume消费者 Kafka集成Spark 生产者 object SparkKafkaProducer{def main(args:Array[S…