转贴自 http://www.hooto.com/home/rui/doc/node/list/treeid/1056/page/1
1.6 在 WHERE 子句中引用取别名的列
Q: 在 where 子句中引用别名 A: 将查询作为内联视图就可以引用其中的别名
Oracle,MySQL,PostgreSQL,MSSQL,DB2 (使用内联视图) SELECT * FROM ( SELECT sal AS salary,comm AS commission FROM emp ) x WHERE salary < 5000 AND commission IS NOT NULL
+--------+------------+ | salary | commission | +--------+------------+ | 1600 | 300 | | 1250 | 500 | | 1250 | 1400 | | 1500 | 0 | +--------+------------+ 4 rows in set (0.00 sec)
PS: 子句优先级 FROM -> WHERE -> SELECT
1.7 连接列值
Q: 将多列值连接作为一列返回 A: 使用内置函数 “concat”
DB2,Oracle,PostgreSQL ( concat函数,以及简写 “||” 双竖线连接符 ) SELECT ename || ‘ WORKS AS A ‘ || job AS msg FROM emp WHERE deptno = 10
MySQL ( concat函数 ) SELECT concat(ename,‘ WORKS AS A ‘,job) AS msg FROM emp WHERE deptno = 10
SQL Server ( “+” 运算符连接) SELECT ename + ‘ WORKS AS A ‘ + job AS msg FROM emp WHERE deptno = 10
+—————————+ | msg | +—————————+ | CLARK WORKS AS A MANAGER | | KING WORKS AS A PRESIDENT | | MILLER WORKS AS A CLERK | +—————————+ 3 rows in set (0.04 sec)
1.8 在 SELECT 子句中使用条件逻辑
Q: 在 SELECT 语句中,对数值执行 IF-ELSE 操作 A: 使用 CASE
Oracle,DB2 (使用 CASE ) SELECT ename,sal, CASE WHEN sal <= 2000 THEN 'UNDERPAID' WHEN sal >= 4000 THEN ‘OVERPAID’ ELSE ‘OK’ END AS status FROM emp
+——–+——+———–+ | ename | sal | status | +——–+——+———–+ | SMITH | 800 | UNDERPAID | | ALLEN | 1600 | UNDERPAID | | WARD | 1250 | UNDERPAID | | JONES | 2975 | OK | | MARTIN | 1250 | UNDERPAID | | BLAKE | 2850 | OK | | CLARK | 2450 | OK | | SCOTT | 3000 | OK | | KING | 5000 | OVERPAID | | TURNER | 1500 | UNDERPAID | | ADAMS | 1100 | UNDERPAID | | JAMES | 950 | UNDERPAID | | FORD | 3000 | OK | | MILLER | 1300 | UNDERPAID | +——–+——+———–+ 14 rows in set (0.05 sec)
1.9 限制返回的行数
Q: 如何限制查询中返回的行数 A: 使用数据库内置函数
DB2 ( 使用 FETCH FIRST 子句 ) SELECT * FROM emp FETCH FIRST 5 ROWS ONLY
MySQL,PostgreSQL ( 使用 LIMIT ) SELECT * FROM emp LIMIT 5
Oracle ( 使用 ROWNUM ) SELECT * FROM emp WHERE ROWNUM<= 5 ( ROWNUM = 5 错误的语法 )
SQL Server ( 使用 TOP ) SELECT TOP 5 FROM emp
1.10 随机返回 n 条记录
Q: 从表中随机返回 n 条记录,每次执行返回不同的结果集 A: 使用DBMS内置函数生成随机数值,在 ORDER BY 中使用该函数随机排序
DB2 ( 使用 RAND 内置函数 ) SELECT ename,job FROM emp ORDER BY rand() FETCH FIRST 5 ROWS ONLY
MySQL ( 使用 RAND 内置函数 ) SELECT ename,job FROM emp ORDER BY rand() LIMIT 5
PostgreSQL ( random() ) SELECT ename,job FROM emp ORDER BY random() LIMIT 5
Oracle ( 使用 DBMS_RANDOM 包中的内置函数 VALUE ) SELECT * FROM ( SELECT ename,job FROM emp ORDER BY dbms_random.value() ) WHERE ROWNUM <= 5
SQL Server ( newid() ) SELECT top 5 ename,job FROM emp ORDER BY newid()
PS: 在 ORDER BY 子句中指定数字常量时,是要求根据 SELECT 列表中相应位置的列来排序,在 ORDER BY 子句中使用函数时,则按函数在每一行计算结果排序
1.11 查找空值
Q: 查找某列值为空的行 A: 使用 IS NULL,或者 IS NOT NULL
Oracle,DB2 (使用IS NULL,IS NOT NULL) SELECT * FROM emp WHERE comm IS NULL
1.12 将空值替换为实际值
Q: 用非空值替换空值 A: 使用 COALESCE
Oracle,DB2 (使用COALESCE()) SELECT coalesce(comm,0) FROM emp
+——————-+ | coalesce(comm,0) | +——————-+ | 0 | | 300 | | 500 | | 0 | | 1400 | | 0 | | 0 | | 0 | | 0 | | 0 | | 0 | | 0 | | 0 | | 0 | +——————-+ 14 rows in set (0.00 sec)
1.13 按模式搜索
Q: 需要返回匹配特定子串或模式的行,比如在部门 10 和 20 中,返回名字有一个 “I”,或者职务中带有 “ER” 的员工行 A: 使用 LIKE 运算符, 通配符 “%”
Oracle,DB2 (使用 LIKE) SELECT ename,job FROM emp WHERE deptno IN (10,20) AND (ename LIKE ‘%I%’ OR job LIKE ‘%ER’)
+——–+———–+ | ename | job | +——–+———–+ | SMITH | CLERK | | JONES | MANAGER | | CLARK | MANAGER | | KING | PRESIDENT | | MILLER | CLERK | +——–+———–+ 5 rows in set (0.00 sec)
2.3 按子串排序
2.3 按子串排序 Q: 按照字符串某一部分排序,如按照某字段值的最后两个字符排序 A: 使用 DBMS 内置函数
DB2,PostgreSQL ( substr() ) SELECT ename,job FROM emp ORDER BY substr(job,length(job) - 2)
+——–+———–+ | ename | job | +——–+———–+ | KING | PRESIDENT | | SMITH | CLERK | | JAMES | CLERK | | ADAMS | CLERK | | MILLER | CLERK | | BLAKE | MANAGER | | CLARK | MANAGER | | JONES | MANAGER | | MARTIN | SALESMAN | | TURNER | SALESMAN | | WARD | SALESMAN | | ALLEN | SALESMAN | | FORD | ANALYST | | SCOTT | ANALYST | +——–+———–+ 14 rows in set (0.05 sec)
SQL Server ( substring() ) SELECT ename,job FROM emp ORDER BY substring(job,len(job) - 2,2)
2.4 对字母数字混合的数据排序
2.4 对字母数字混合的数据排序 Q: 现有字母和数字混合的数据,按照数字或字母部分来排序,建立如下视图:
create view V as select ename ||’ ‘|| deptno as data from emp ;
select * from V ;
data ———– SMITH 20 ALLEN 30 WARD 30 JONES 20 MARTIN 30 BLAKE 30 CLARK 10 SCOTT 20 KING 10 TURNER 30 ADAMS 20 JAMES 30 FORD 20 MILLER 10 (14 rows)
分别实现对 data 的字母和数字排序
A: 使用函数 replace(),translate()
Oracle,PostgreSQL /* order by deptno */ select data from V order by replace(data, replace( translate(data,‘0123456789′,‘##########’),‘#’,”),”) data ———– MILLER 10 CLARK 10 KING 10 SCOTT 20 JONES 20 SMITH 20 ADAMS 20 FORD 20 WARD 30 TURNER 30 ALLEN 30 BLAKE 30 MARTIN 30 JAMES 30 (14 rows)
/* order by ename */ select data from V order by replace( translate(data,”)
data ———– ADAMS 20 ALLEN 30 BLAKE 30 CLARK 10 FORD 20 JAMES 30 JONES 20 KING 10 MARTIN 30 MILLER 10 SCOTT 20 SMITH 20 TURNER 30 WARD 30 (14 rows)
DB2 (隐式类型转换严格,为使视图有效,需要将 deptno 转换成 char 类型) /* order by deptno */ select * from ( select ename ||’ ‘|| cast(deptno as char(2)) as data from emp ) V order by replace(data,‘##########’,‘0123456789′),”)
/* order by ename */ select * from ( select ename ||’ ‘|| cast(deptno as char(2)) as data from emp ) V order by replace( translate(data,”)
MySQL,SQL Server (不支持 translate(),无解决方案)
2.5 处理排序空值
2.5 处理排序空值 Q: 指定是否将空值字段行排在最后 A: 使用 case 表达式在 order by 子句中增加标记列; 或 RDBMS 特殊方案
DB2,SQL Server,Oracle /* all nulls last */ select ename,comm,is_null from ( select ename, case when comm is null then 0 else 1 end as is_null from emp ) x order by is_null desc,comm
ename | sal | comm | is_null ——–+——+——+——— TURNER | 1500 | 0 | 1 ALLEN | 1600 | 300 | 1 WARD | 1250 | 500 | 1 MARTIN | 1250 | 1400 | 1 SCOTT | 3000 | | 0 KING | 5000 | | 0 ADAMS | 1100 | | 0 JAMES | 950 | | 0 FORD | 3000 | | 0 SMITH | 800 | | 0 MILLER | 1300 | | 0 JONES | 2975 | | 0 BLAKE | 2850 | | 0 CLARK | 2450 | | 0 (14 rows)
/* all nulls first */ select ename, case when comm is null then 0 else 1 end as is_null from emp ) x order by is_null,comm
ename | sal | comm | is_null ——–+——+——+——— MILLER | 1300 | | 0 ADAMS | 1100 | | 0 JAMES | 950 | | 0 FORD | 3000 | | 0 SMITH | 800 | | 0 JONES | 2975 | | 0 BLAKE | 2850 | | 0 CLARK | 2450 | | 0 SCOTT | 3000 | | 0 KING | 5000 | | 0 TURNER | 1500 | 0 | 1 ALLEN | 1600 | 300 | 1 WARD | 1250 | 500 | 1 MARTIN | 1250 | 1400 | 1
Oracle 9i or later (使用 “nulls last”,“nulls first”) /* all nulls last */ select ename,comm from emp order by comm nulls last
/* all nulls first */ select ename,comm from emp order by comm nulls first
2.6 根据数据项的键排序
2.6 根据数据项的键排序 Q: 针对某条件逻辑排序,如: job = ‘SALESMAN’ 按照 comm 排序,否则根据 sal 排序 A: 使用 case 表达式来动态改变如何对结果排序
select ename,job,comm from emp order by case when job = ‘SALESMAN’ then comm else sal end
ename | sal | job | comm ——–+——+———–+—— TURNER | 1500 | SALESMAN | 0 ALLEN | 1600 | SALESMAN | 300 WARD | 1250 | SALESMAN | 500 SMITH | 800 | CLERK | JAMES | 950 | CLERK | ADAMS | 1100 | CLERK | MILLER | 1300 | CLERK | MARTIN | 1250 | SALESMAN | 1400 CLARK | 2450 | MANAGER | BLAKE | 2850 | MANAGER | JONES | 2975 | MANAGER | SCOTT | 3000 | ANALYST | FORD | 3000 | ANALYST | KING | 5000 | PRESIDENT | (14 rows) (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|