--比如我想通过一段sql查询当前用户下所有的表信息,如数据量大小,统计分析,其表的字段,及其说明
--我们用两种方法来满足需求
--1.平时我们实现此步骤会使用join操作实现:
SELECT rownum AS max_size,
s.table_name,
s.last_analyzed,
s.num_rows,
o.column_name,
o.column_name
FROM user_tables s
JOIN user_col_comments o
ON s.table_name = o.table_name
WHERE s.num_rows >= 1000
AND s.table_name LIKE 'HYZ%';
--2.使用with...as实现
WITH usertable AS --定义名称时不要和表名相同
(SELECT s.table_name, s.last_analyzed, s.num_rows FROM user_tables s),
usercolcomments AS --定义名称时不要和表名相同
(SELECT o.table_name, o.column_name, o.comments FROM user_col_comments o)
SELECT rownum AS max_size,
s.table_name,
s.last_analyzed,
s.num_rows,
o.column_name,
o.column_name
FROM usertable s
JOIN usercolcomments o
ON s.table_name = o.table_name
WHERE s.num_rows >= 1000
AND s.table_name LIKE 'HYZ%';
--此两种实现方式都实现了同样的需求,以上需求并看不出with..as的优势,如果我们增加如下需求
--查询表空间的相关详情数据
SELECT a.tablespace_name AS 表空间名,
SUM(a.bytes) AS "总空间(B)",
SUM(b.bytes) AS "已使用(B)",
SUM(c.bytes) AS "剩余空间(B)",
SUM((b.bytes * 100) / a.bytes) "已使用比例(%)",
SUM((c.bytes * 100) / a.bytes) "空闲比例(%) ",
(SUM(c.bytes) / 1024 / 1024 / 1024) AS "剩余空间(GB)"
FROM sys.sm$ts_avail a, sys.sm$ts_used b, sys.sm$ts_free c
WHERE a.tablespace_name = b.tablespace_name
AND a.tablespace_name = c.tablespace_name
GROUP BY a.tablespace_name
ORDER BY a.tablespace_name;
--此时我们使用join的时候发现把此表放进去以后
SELECT rownum AS max_size,
s.table_name,
s.last_analyzed,
s.num_rows,
o.column_name,
o.column_name,
k.表空间名,
k."总空间(B)",
k."已使用(B)",
k."剩余空间(B)",
k."已使用比例(%)",
k."空闲比例(%) ",
k."剩余空间(GB)"
FROM user_tables s
JOIN user_col_comments o
ON s.table_name = o.table_name
JOIN (SELECT a.tablespace_name AS 表空间名,
SUM(a.bytes) AS "总空间(B)",
SUM(b.bytes) AS "已使用(B)",
SUM(c.bytes) AS "剩余空间(B)",
SUM((b.bytes * 100) / a.bytes) "已使用比例(%)",
SUM((c.bytes * 100) / a.bytes) "空闲比例(%) ",
(SUM(c.bytes) / 1024 / 1024 / 1024) AS "剩余空间(GB)"
FROM sys.sm$ts_avail a, sys.sm$ts_used b, sys.sm$ts_free c
WHERE a.tablespace_name = b.tablespace_name
AND a.tablespace_name = c.tablespace_name
GROUP BY a.tablespace_name
ORDER BY a.tablespace_name) k
ON k.表空间名 = s.tablespace_name
WHERE s.num_rows >= 1000
AND s.table_name LIKE 'HYZ%';
--无论是美观还是后期如果新增复杂的sql使用join或left join连接都十分的不方便,如果稍有报错还得仔细查看
--如果我们使用with...as
WITH usertable AS --定义名称时不要和表名相同
(SELECT s.table_name, s.last_analyzed, s.num_rows, s.tablespace_name
FROM user_tables s),
usercolcomments AS --定义名称时不要和表名相同
(SELECT o.table_name, o.column_name, o.comments FROM user_col_comments o),
tablespaces AS
(SELECT a.tablespace_name AS 表空间名,
SUM(a.bytes) AS "总空间(B)",
SUM(b.bytes) AS "已使用(B)",
SUM(c.bytes) AS "剩余空间(B)",
SUM((b.bytes * 100) / a.bytes) "已使用比例(%)",
SUM((c.bytes * 100) / a.bytes) "空闲比例(%) ",
(SUM(c.bytes) / 1024 / 1024 / 1024) AS "剩余空间(GB)"
FROM sys.sm$ts_avail a, sys.sm$ts_used b, sys.sm$ts_free c
WHERE a.tablespace_name = b.tablespace_name
AND a.tablespace_name = c.tablespace_name
GROUP BY a.tablespace_name
ORDER BY a.tablespace_name)
SELECT rownum AS max_size,
s.table_name,
s.last_analyzed,
s.num_rows,
o.column_name,
o.column_name,
k.表空间名,
k."总空间(B)",
k."已使用(B)",
k."剩余空间(B)",
k."已使用比例(%)",
k."空闲比例(%) ",
k."剩余空间(GB)"
FROM usertable s
JOIN usercolcomments o
ON s.table_name = o.table_name
JOIN tablespaces k
ON k.表空间名 = s.tablespace_name
WHERE s.num_rows >= 1000
AND s.table_name LIKE 'HYZ%';
--此时我们只需要保证usertable,usercolcomments,tablespaces括号内逻辑无问题,使用时字段补全
--既能保证美观,又能对复杂的sql进行临时查询,有时候我们会采用临时表去处理此类,方便取数和分析问题
--但是如果使用with...as对我们的工作和需求是事半功倍的
--重要的是再复杂的逻辑我们并不需要建实际的临时表,避免了如果稍有逻辑的问题,又得重新建临时表
--我们可以尝试把所有逻辑或运算进行如下处理
WITH usertable AS --定义名称时不要和表名相同
(SELECT s.table_name, s.last_analyzed, s.num_rows, s.tablespace_name
FROM user_tables s),
usercolcomments AS --定义名称时不要和表名相同
(SELECT o.table_name, o.column_name, o.comments FROM user_col_comments o),
tablespaces AS
(SELECT a.tablespace_name AS tablespace_name,
SUM(a.bytes) AS total_space,
SUM(b.bytes) AS used_space,
SUM(c.bytes) AS remaining_space,
SUM((b.bytes) / a.bytes) AS used_space_bl,
SUM((c.bytes) / a.bytes) remaining_space_bl,
(SUM(c.bytes)) AS remaining_space_gb
FROM sys.sm$ts_avail a, sys.sm$ts_used b, sys.sm$ts_free c
WHERE a.tablespace_name = b.tablespace_name
AND a.tablespace_name = c.tablespace_name
GROUP BY a.tablespace_name
ORDER BY a.tablespace_name)
--把所有的复杂的运算放到以下sql处理,使得上面的在复杂的逻辑也能保持整个sql的美观
SELECT rownum AS max_size,
s.table_name,
s.last_analyzed,
s.num_rows,
o.column_name,
o.column_name,
k.tablespace_name,
k.total_space AS "总空间(B)",
k.used_space AS "已使用(B)",
k.remaining_space AS "剩余空间(B)",
k.used_space_bl * 100 AS "已使用比例(%)",
k.remaining_space_bl * 100 AS "空闲比例(%) ",
k.remaining_space_gb / 1024 / 1024 / 1024 AS "剩余空间(GB)"
FROM usertable s
JOIN usercolcomments o
ON s.table_name = o.table_name
JOIN tablespaces k
ON k.tablespace_name = s.tablespace_name
WHERE s.num_rows >= 1000
AND s.table_name LIKE 'HYZ%';