我工作中遇到的SQL(长期更新)


----1
SELECT B.BRID ,A.CUR,A.FINANRANK FROM 
   (SELECT SUM(APPBAL) CUR,BRID,ROW_NUMBER() OVER(order by SUM(APPBAL) ASC) FINANRANK FROM IFS_FINANCE 
   WHERE SIGNDATE=(SELECT LAST_YEAR (accdate) FROM IFS_BANKCTL)

GROUP BY BRID) A RIGHT JOIN IFS_BRANCH B ON A.BRID=B.BRID 

其中ifs_branch65条数据,查询出来的时候也是65条数据!但是他不是以finanrank来排的序,而是以brid,brid在ifs_branch中是主键

我工作中遇到的SQL(长期更新)_第1张图片

所以我这样写

SELECT B.BRID ,A.CUR,A.FINANRANK FROM 
   (SELECT SUM(APPBAL) CUR,BRID,ROW_NUMBER() OVER(order by SUM(APPBAL) ASC) FINANRANK FROM IFS_FINANCE 
   WHERE SIGNDATE=(SELECT LAST_YEAR (accdate) FROM IFS_BANKCTL)
GROUP BY BRID) A RIGHT JOIN IFS_BRANCH B ON A.BRID=B.BRID ORDER BY a.finanrank 

我工作中遇到的SQL(长期更新)_第2张图片


------2

看别人写的一个sql,由于还不是很熟悉sql,一下有点晕

这是一个求字段完整率的SQL

SELECT BRID,CUSTNUM VIPJCUSTNUM,DECIMAL(DECIMAL((DECIMAL(NUM+NUM1+NUM3+NUM4+NUM5,18,4))/CUSTNUM,18,4)/6,18,4) vipjcustingm FROM 
(
SELECT 
D.BRID,   
COALESCE(D.CUSTCLASS,'1') CUSTCLASS,
COUNT(*) CUSTNUM,
sum(NUM6) NUM, 
sum(CASE WHEN ((COMPADDR IS NOT NULL AND COMPADDR<>'') OR
(FAMILYADDR IS NOT NULL AND FAMILYADDR<>'')) THEN 1 ELSE 0 end)NUM1 ,
SUM(CASE WHEN BIRTHDAY       IS NOT NULL  THEN 1 ELSE 0 END) NUM3,                  
SUM(CASE WHEN CONTACTCHANNEL IS NOT NULL AND CONTACTCHANNEL !='' THEN 1 ELSE 0 END )NUM4,
SUM(CASE WHEN MARRIAGE       IS NOT NULL AND MARRIAGE       !='' THEN 1 ELSE 0 END )NUM5
FROM 
IFS_CUSTOMER 
A LEFT JOIN 
(SELECT CUSTID,
CASE
WHEN (COMPHONE <>MOBILEPHONE AND COMPHONE IS NOT NULL AND MOBILEPHONE IS NOT NULL AND COMPHONE<>'' AND MOBILEPHONE<>'' )
OR (COMPHONE<>iPHONE AND COMPHONE IS NOT NULL AND iPHONE IS NOT NULL AND COMPHONE<>'' AND iPHONE<>'')
OR (COMPHONE<>PHONE AND COMPHONE IS NOT NULL AND PHONE IS NOT NULL AND COMPHONE<>'' AND PHONE<>'')
OR (MOBILEPHONE<>iPHONE AND MOBILEPHONE IS NOT NULL AND iPHONE IS NOT NULL AND MOBILEPHONE<>'' AND iPHONE<>'')
OR (MOBILEPHONE<>PHONE AND MOBILEPHONE IS NOT NULL AND PHONE IS NOT NULL AND MOBILEPHONE<>'' AND PHONE<>'')
OR (PHONE<>iPHONE AND PHONE IS NOT NULL AND iPHONE IS NOT NULL AND PHONE<>'' AND iPHONE<>'')THEN 2  
WHEN (COMPHONE IS NOT NULL AND COMPHONE<>'')  OR (MOBILEPHONE IS NOT NULL AND MOBILEPHONE<>'')
OR (iPHONE IS NOT NULL AND iPHONE<>'') OR (PHONE IS NOT NULL AND PHONE<>'') THEN 1 ELSE 0  END NUM6
FROM IFS_CUSTOMER) B 
ON A.CUSTID = B.CUSTID
 LEFT JOIN 
 IFS_CUSTVALUE D ON A.CUSTID = D.CUSTID  
 WHERE D.CUSTCLASS = '2'
 GROUP BY D.BRID, COALESCE(D.CUSTCLASS,'1')
 ) X

一下晕了,这是什么逻辑呀,我就剪掉一些查询字段,然后就看到如下SQL,呵呵,好看多了

SELECT BRID,CUSTNUM VIPJCUSTNUM,DECIMAL(DECIMAL((DECIMAL(NUM+NUM1+NUM3+NUM4+NUM5,18,4))/CUSTNUM,18,4)/6,18,4) vipjcustingm FROM 
(
SELECT 
D.BRID,   
COALESCE(D.CUSTCLASS,'1') CUSTCLASS,
COUNT(*) CUSTNUM,
sum(NUM6) NUM
FROM 
--下面三个表的连接
IFS_CUSTOMER 
A LEFT JOIN 

(SELECT CUSTID,
FROM IFS_CUSTOMER) B
 
ON A.CUSTID = B.CUSTID
 LEFT JOIN 
 
 IFS_CUSTVALUE D 
 
 
 ON A.CUSTID = D.CUSTID  
 WHERE D.CUSTCLASS = '2'
 GROUP BY D.BRID, COALESCE(D.CUSTCLASS,'1')
 ) X
 


----3

遇到一个有关时间的SQL

SELECT DISTINCT rmdtype FROM IFS_DEPTDUErmd WHERE DUEDATE>(CURRENT DATE +3 MONTH) 

大于当前时间3个月的数据


--------4

我工作中遇到的SQL(长期更新)_第3张图片

我工作中遇到的SQL(长期更新)_第4张图片

----表表达式

我工作中遇到的SQL(长期更新)_第5张图片

我工作中遇到的SQL(长期更新)_第6张图片

-------公共表达式

我工作中遇到的SQL(长期更新)_第7张图片

WITH
PAYLEVEL AS
(SELECT EMPNO, EDLEVEL, YEAR(HIREDATE) AS HIREYEAR,
SALARY+BONUS+COMM AS TOTAL_PAY
FROM EMPLOYEE
WHERE EDLEVEL > 16),


PAYBYED (EDUC_LEVEL, YEAR_OF_HIRE, AVG_TOTAL_PAY) AS
(SELECT EDLEVEL, HIREYEAR, AVG(TOTAL_PAY)
FROM PAYLEVEL
GROUP BY EDLEVEL, HIREYEAR)



--

SELECT EMPNO, EDLEVEL, YEAR_OF_HIRE, TOTAL_PAY, DECIMAL(AVG_TOTAL_PAY,7,2)
FROM PAYLEVEL, PAYBYED
WHERE EDLEVEL = EDUC_LEVEL
AND HIREYEAR = YEAR_OF_HIRE
AND TOTAL_PAY < AVG_TOTAL_PAY



我工作中遇到的SQL(长期更新)_第8张图片





------SQL执行顺序

问题的引出

我工作中遇到的SQL(长期更新)_第9张图片

SELECT EMPNO, LASTNAME
FROM EMPLOYEE
WHERE WORKDEPT = 'A00'
AND SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE
WHERE WORKDEPT = 'A00')


我工作中遇到的SQL(长期更新)_第10张图片


我工作中遇到的SQL(长期更新)_第11张图片

最后这句话很重要,他暗含了SQL的执行顺序!接着往下看。。。。。


我工作中遇到的SQL(长期更新)_第12张图片

我工作中遇到的SQL(长期更新)_第13张图片

SELECT LASTNAME, WORKDEPT, EDLEVEL
FROM EMPLOYEE E1
WHERE EDLEVEL > (SELECT AVG(EDLEVEL)
FROM EMPLOYEE E2
WHERE E2.WORKDEPT = E1.WORKDEPT)

我工作中遇到的SQL(长期更新)_第14张图片

SELECT LASTNAME, DEPTNAME, EDLEVEL
FROM EMPLOYEE E1, DEPARTMENT
WHERE E1.WORKDEPT = DEPARTMENT.DEPTNO
AND EDLEVEL > (SELECT AVG(EDLEVEL)
FROM EMPLOYEE E2
WHERE E2.WORKDEPT = E1.WORKDEPT)
结果为:
LASTNAME            DEPTNAME                 EDLEVEL
--------------- ----------------------------- -------
HAAS 		SPIFFY COMPUTER SERVICE DIV.     18
LUCCHESSI 	SPIFFY COMPUTER SERVICE DIV.     19
KWAN 		INFORMATION CENTER               20
PIANKA 		MANUFACTURING SYSTEMS 		17
SCOUTTEN 	MANUFACTURING SYSTEMS 		17
JONES		MANUFACTURING SYSTEMS 		17
LUTZ 		MANUFACTURING SYSTEMS 		18
PULASKI 	ADMINISTRATION SYSTEMS 		16
MARINO 		ADMINISTRATION SYSTEMS 		17
JOHNSON 	ADMINISTRATION SYSTEMS 		16
HENDERSON 	OPERATIONS 			16
SCHNEIDER 	OPERATIONS			 17
MEHTA 		SOFTWARE SUPPORT 		16
GOUNOT 		SOFTWARE SUPPORT 		16




我工作中遇到的SQL(长期更新)_第15张图片


我工作中遇到的SQL(长期更新)_第16张图片

当我一直看到这的时候,出现了疑问,是在不明白sql的执行顺序是什么,当我想当然的认为他就是那样执行的时候,问题就不存在了

比如最开始的那个相关性

SELECT E1.EMPNO, E1.LASTNAME, E1.WORKDEPT
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE E2
WHERE E2.WORKDEPT = E1.WORKDEPT)
ORDER BY E1.WORKDEPT

我在想:他是先查内select找到AVG呢,还是先找外select找到E1呢;

我说是想找内,到了E1的时候,再找外E1,得到workdept,得到该workdept的AVG,比较该条记录,如果大于,输出,然后接着下一行,每一行都会执行内,外select,尽管之前已经得到avg;是这样的吗????





------数字表示列

SELECT * FROM ORG

我工作中遇到的SQL(长期更新)_第17张图片

下面这两条sql的执行结果是一样的

SELECT * FROM ORG ORDER BY 1
SELECT * FROM ORG ORDER BY deptnumb

注意:后面的1是按照select来排序的,而不是数据库的列顺序;如:

SELECT MANAGER,DIVISION,LOCATION,DEPTNUMB FROM ORG ORDER BY 1

是按照manager来排序的

再看看:

SELECT * FROM ORG WHERE 900>manager

是不是有点陌生呢?呵呵

SELECT * FROM ORG WHERE manager<900

这样是不是就熟悉了!


你可能感兴趣的:(sql,代表)