當前位置:首頁 » 編程語言 » sql子查詢順序
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql子查詢順序

發布時間: 2023-01-31 21:18:31

A. 資料庫 sql語句 子查詢執行過程

子查詢執行過程,可以用以下例子來說明:

語句如下:

select*fromscorewheresidin(selectsidfromstudentwhere班級='一班')

在sql語句中,資料庫先執行的是括弧中的部分,得出student表中一班學生的sid,然後再在score表中選出sid為一班id的哪些學生的詳細內容。

B. 請問這個sql語句的執行順序是怎麼樣的

現在子查詢,再是外面的查詢

C. oracle SQL子查詢與主查詢誰先執行

毫無疑問是主查詢先。
例如
select * from A
WHERE id < 5
AND ID IN (SELECT ID FROM B WHERE xxxx)
這里由於是and連接,不存在優先順序問題。所以查詢的時候先全表掃描 id < 5的,然後再多一個條件,id in 子查詢。此時,先去查詢子查詢。然後再回到主查詢。

從這個例子可以看出每次掃描都要做子查詢掃描,從而導致了效率低下。這也是為什麼不推薦子查詢的根本原因。

D. SQL必知必會(二)函數、子查詢

#文本處理函數

UPPER()     --大寫

LOWER()    --小寫

SOUNDEX()   --讀音類似

LENGTH()    --字元串長度

#日期和時間處理函數

SELECT order_code

FROM order_table

WHERE DATEPART(yy,order_date)=2012

#to_char()函數提取日期成分,MySQL可用year()函數提取年份

SELECT order_num

FROM order_table

WHERE to_number(to_char(order_date,'YYYY'))=2012;    --to_char提取日期成分to_number轉化為數值

SELECT order_num

FROM order_table

WHERE order_date BETWEEN to_date('01-01-2012') AND to_date('12-31--2012');    --字元串轉日期

#數值處理函數

ABS()    --絕對值

COS()    --餘弦

EXP()    --指數值

PI()   --圓周率

SIN()    --正弦

SQRT()    --平方根

TAN()    --正切

#平均數AVG()

SELECT AVG(a) AS avg_a

FROM tableA

WHERE a='DLL01';

#計數

SELECT COUNT(*)  AS num_cust              --對所有行計數,不管是否NULL值

FROM tableA;

SELECT COUNT(a) AS num_a          --指定了列名,會忽略NULL值

FROM tableA;

#最值

MAX()和MIN(),忽略NULL值

#總值SUM(),忽略NULL值

SELECT SUM(price*quantity) AS total_price

FROM tableA

WHERE order_code=20008

#以上聚集函數只包含不同值

SELECT AVG(DISTINCT order_price) AS avg_price

FROM tableA

WHERE id='DLL01';

兩個子句:GROUP BY 和 HAVING

#GROUP BY創建分組HAVING過濾分組

SELECT vend_id, COUNT(*) AS num_prods

FROM tableA

WHERE price>=4

GROUP BY vend_id

HAVING COUNT(*)>=2;   

ORDER BY price    --GROUP BY在WHERE之後在ORDER   BY之前

SELECT

FROM

WHERE

GROUP BY

HAVING

ORDER BY

#子查詢順序為從內而外

SELECT order_num 

FROM tableA

WHERE id='DLL01';

(輸出20007和20008)

SELECT id

FROM tableB

WHERE order_num IN(20007,20008);

#合並為子查詢。只能查詢單個列

SELECT id

FROM tableB

WHERE order_num IN (SELECT order_num FROM tableA WHERE id='DLL01')

SELECT  cust_name,

                cust_state

                (SELECT COUNT(*) 

                 FROM Orders

                WHERE Orders.cust_id=Customers.cust_id) AS orders

FROM Customers

ORDER BY cust_name;

#Orders.cust_id=Customers.cust_id完全限定列名,在兩張表中名字相同列拿出來比較,防止歧義

E. SQL查詢語句

一、簡單查詢語句

1. 查看錶結構

SQL>DESC emp;

2. 查詢所有列

SQL>SELECT * FROM emp;

3. 查詢指定列

SQL>SELECT empmo, ename, mgr FROM emp;

SQL>SELECT DISTINCT mgr FROM emp; 只顯示結果不同的項

4. 查詢指定行

SQL>SELECT * FROM emp WHERE job='CLERK';

5. 使用算術表達式

SQL>SELECT ename, sal*13+nvl(comm,0) FROM emp;

nvl(comm,1)的意思是,如果comm中有值,則nvl(comm,1)=comm; comm中無值,則nvl(comm,1)=0。

SQL>SELECT ename, sal*13+nvl(comm,0) year_sal FROM emp; (year_sal為別名,可按別名排序)

SQL>SELECT * FROM emp WHERE hiredate>'01-1月-82';

6. 使用like操作符(%,_)

%表示一個或多個字元,_表示一個字元,[charlist]表示字元列中的任何單一字元,[^charlist]或者[!charlist]不在字元列中的任何單一字元。

SQL>SELECT * FROM emp WHERE ename like 'S__T%';

7. 在where條件中使用In

SQL>SELECT * FROM emp WHERE job IN ('CLERK','ANALYST');

8. 查詢欄位內容為空/非空的語句

SQL>SELECT * FROM emp WHERE mgr IS/IS NOT NULL;

9. 使用邏輯操作符號

SQL>SELECT * FROM emp WHERE (sal>500 or job='MANAGE') and ename like 'J%';

10. 將查詢結果按欄位的值進行排序

SQL>SELECT * FROM emp ORDER BY deptno, sal DESC; (按部門升序,並按薪酬降序)

二、復雜查詢

1. 數據分組(max,min,avg,sum,count)

SQL>SELECT MAX(sal),MIN(age),AVG(sal),SUM(sal) from emp;

SQL>SELECT * FROM emp where sal=(SELECT MAX(sal) from emp));

SQL>SELEC COUNT(*) FROM emp;

2. group by(用於對查詢結果的分組統計) 和 having子句(用於限制分組顯示結果)

SQL>SELECT deptno,MAX(sal),AVG(sal) FROM emp GROUP BY deptno;

SQL>SELECT deptno, job, AVG(sal),MIN(sal) FROM emp group by deptno,job having AVG(sal)<2000;

對於數據分組的總結:

a. 分組函數只能出現在選擇列表、having、order by子句中(不能出現在where中)

b. 如果select語句中同時包含有group by, having, order by,那麼它們的順序是group by, having, order by。

c. 在選擇列中如果有列、表達式和分組函數,那麼這些列和表達式必須出現在group by子句中,否則就是會出錯。

使用group by不是使用having的前提條件。

3. 多表查詢

SQL>SELECT e.name,e.sal,d.dname FROM emp e, dept d WHERE e.deptno=d.deptno order by d.deptno;

SQL>SELECT e.ename,e.sal,s.grade FROM emp e,salgrade s WHER e.sal BETWEEN s.losal AND s.hisal;

4. 自連接(指同一張表的連接查詢)

SQL>SELECT er.ename, ee.ename mgr_name from emp er, emp ee where er.mgr=ee.empno;

5. 子查詢(嵌入到其他sql語句中的select語句,也叫嵌套查詢)

5.1 單行子查詢

SQL>SELECT ename FROM emp WHERE deptno=(SELECT deptno FROM emp where ename='SMITH');查詢表中與smith同部門的人員名字。因為返回結果只有一行,所以用“=”連接子查詢語句

5.2 多行子查詢

SQL>SELECT ename,job,sal,deptno from emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno=10);查詢表中與部門號為10的工作相同的員工的姓名、工作、薪水、部門號。因為返回結果有多行,所以用“IN”連接子查詢語句。

in與exists的區別: exists() 後面的子查詢被稱做相關子查詢,它是不返回列表的值的。只是返回一個ture或false的結果,其運行方式是先運行主查詢一次,再去子查詢里查詢與其對 應的`結果。如果是ture則輸出,反之則不輸出。再根據主查詢中的每一行去子查詢里去查詢。in()後面的子查詢,是返回結果集的,換句話說執行次序和 exists()不一樣。子查詢先產生結果集,然後主查詢再去結果集里去找符合要求的欄位列表去。符合要求的輸出,反之則不輸出。

5.3 使用ALL

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ALL (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MAX(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的所有員工工資都高的員工的姓名、薪水和部門號。以上兩個語句在功能上是一樣的,但執行效率上,函數會高 得多。

5.4 使用ANY

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ANY (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MIN(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的任意一個員工工資高(只要比某一員工工資高即可)的員工的姓名、薪水和部門號。以上兩個語句在功能上是 一樣的,但執行效率上,函數會高得多。

5.5 多列子查詢

SQL>SELECT * FROM emp WHERE (job, deptno)=(SELECT job, deptno FROM emp WHERE ename='SMITH');

5.6 在from子句中使用子查詢

SQL>SELECT emp.deptno,emp.ename,emp.sal,t_avgsal.avgsal FROM emp,(SELECT emp.deptno,avg(emp.sal) avgsal FROM emp GROUP BY emp.deptno) t_avgsal where emp.deptno=t_avgsal.deptno AND emp.sal>t_avgsal.avgsal ORDER BY emp.deptno;

5.7 分頁查詢

資料庫的每行數據都有一個對應的行號,稱為rownum.

SQL>SELECT a2.* FROM (SELECT a1.*, ROWNUM rn FROM (SELECT * FROM emp ORDER BY sal) a1 WHERE ROWNUM<=10) a2 WHERE rn>=6;

指定查詢列、查詢結果排序等,都只需要修改最里層的子查詢即可。

5.8 用查詢結果創建新表

SQL>CREATE TABLE mytable (id,name,sal,job,deptno) AS SELECT empno,ename,sal,job,deptno FROM emp;

5.9 合並查詢(union 並集, intersect 交集, union all 並集+交集, minus差集)

SQL>SELECT ename, sal, job FROM emp WHERE sal>2500 UNION(INTERSECT/UNION ALL/MINUS) SELECT ename, sal, job FROM emp WHERE job='MANAGER';

合並查詢的執行效率遠高於and,or等邏輯查詢。

5.10 使用子查詢插入數據

SQL>CREATE TABLE myEmp(empID number(4), name varchar2(20), sal number(6), job varchar2(10), dept number(2)); 先建一張空表;

SQL>INSERT INTO myEmp(empID, name, sal, job, dept) SELECT empno, ename, sal, job, deptno FROM emp WHERE deptno=10; 再將emp表中部門號為10的數據插入到新表myEmp中,實現數據的批量查詢。

5.11 使用了查詢更新表中的數據

SQL>UPDATE emp SET(job, sal, comm)=(SELECT job, sal, comm FROM emp where ename='SMITH') WHERE ename='SCOTT';

F. 請問,在資料庫查詢語句中(SQL SERVER)子查詢的執行順序是怎樣的

打開查詢分析器,輸入相應的查詢語句;
在工具欄中緊鄰資料庫下拉列表的右側,有一個按鈕,叫「顯示預計的執行計劃」,點擊它就可以看到相應的查詢語句的執行順序,不但可以看到子查詢的執行順序,也可以看到每一步執行使用的時間大約占總體時間的百分比。

G. SQL中子查詢的代碼意思

子查詢的結果用來做為查詢的條件
比如子查詢得到 a,b,c 三條數據,那麼上面的查詢條件就是
where pub_id in (a,b,c),得到的查詢結果就是當 pub_id = a或者 pub_id = b 或者 pub_id=c的結果,注意這里是或者,就是查詢結果可能不只一個

H. SQL 子查詢, 如何按照IN的順序查詢

select * where stuId in (111,333,222,444,888,555)
ORDER BY PATINDEX('% ' + CONVERT(nvarchar(4000), stuId) + ' %', ' ' + CONVERT(nvarchar(4000), Replace('(111,333,222,444,888,555', ',',' , ')) + ' ')

I. sql的執行順序 與 游標

最近項目中使用了很多大sql,在編碼時sql經常出現執行錯誤,記錄下sql的執行順序,在編碼時就考慮全面,省的之後還要繼續花時間進行試驗調試。

(8)SELECT (9)DISTINCT (11)<Top Num> <select list>

(1)FROM [left_table]

(3)<join_type> JOIN <right_table>

(2)ON <join_condition>

(4)WHERE <where_condition>

(5)GROUP BY <group_by_list>

(6)WITH <CUBE | RollUP>

(7)HAVING <having_condition>

(10)ORDER BY <order_by_list>

1.FROM: 對FROM子句中的前兩個表執行笛卡爾積(Cartesian proct)(交叉聯接),生成虛擬表VT1

2.ON: 對VT1應用ON篩選器。只有那些使為真的行才被插入VT2。

3.OUTER(JOIN): 如 果指定了OUTER JOIN(相對於CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部聯接把左表標記為保留表,右外部聯接把右表標記為保留表,完全外部聯接把兩個表都標記為保留表)中未找到匹配的行將作為外部行添加到 VT2,生成VT3.如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重復執行步驟1到步驟3,直到處理完所有的表為止。

4.WHERE: 對VT3應用WHERE篩選器。只有使為true的行才被插入VT4.

5.GROUP BY: 按GROUP BY子句中的列列表對VT4中的行分組,生成VT5.

6.CUBE|ROLLUP: 把超組(Suppergroups)插入VT5,生成VT6.

7.HAVING: 對VT6應用HAVING篩選器。只有使為true的組才會被插入VT7.

8.SELECT: 處理SELECT列表,產生VT8.

9.DISTINCT: 將重復的行從VT8中移除,產生VT9.

10.ORDER BY: 將VT9中的行按ORDER BY 子句中的列列表排序,生成游標(VC10).

11.TOP: 從VC10的開始處選擇指定數量或比例的行,生成表VT11,並返回調用者。

註:步驟10,按ORDER BY子句中的列列表排序上步返回的行,返回遊標VC10.這一步是第一步也是唯一一步可以使用SELECT列表中的列別名的步驟。這一步不同於其它步驟的 是,它不返回有效的表,而是返回一個游標。SQL是基於集合理論的。集合不會預先對它的行排序,它只是成員的邏輯集合,成員的順序無關緊要。對表進行排序 的查詢可以返回一個對象,包含按特定物理順序組織的行。ANSI把這種對象稱為游標。理解這一步是正確理解SQL的基礎。

因為這一步不返回表(而是返回遊標),使用了ORDER BY子句的查詢不能用作表表達式。表表達式包括:視圖、內聯表值函數、子查詢、派生表和共用表達式。它的結果必須返回給期望得到物理記錄的客戶端應用程序。例如,下面的派生表查詢無效,並產生一個錯誤:select * from(select orderid,customerid from orders order by orderid) as d

在SQL中,表表達式中不允許使用帶有ORDER BY子句的查詢,而在T—SQL中卻有一個例外(應用TOP選項)。所以要記住,不要為表中的行假設任何特定的順序。換句話說,除非你確定要有序行,否則不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要執行有序索引掃描或使用排序運行符。

參考:

https://www.cnblogs.com/knowledgesea/p/3699851.html

https://www.cnblogs.com/

J. sql語句執行順序之group by、order by

1、先執行group by後執行order by,如果相同id的記錄只獲取id大的一條記錄,使用子查詢(先排序後分組):

select * from (select * from table1 order by id desc limit 9999) a group by type_id;

PS:group by需要和limit配合使用,不使用limit語句會自動被優化掉group by無效。

2、欄位值為0的記錄不分組,欄位值大於0的記錄進行分組:

方法1:使用union all

SELECT * FROM `table1` WHERE name='0' UNION ALL SELECT * FROM `table1` WHERE name!='0' group by name;

方法2:使用case when :select的時候判斷id是否等於0,等於0的話則賦值,然後再使用group by分組

select * from (select o.add_time,og.id,(CASE WHEN og.proct_id<1 THEN o.add_time ELSE og.proct_id END) as proct_id from order as o left join order_goods as og on o.order_id=og.order_id order by o.add_time desc limit 9999) table1 group by proct_id order by add_time desc

拓展:(使用上面sql)如果proct_id不為空,需要加上判斷只獲取開啟展示狀態的proct數據:

select * from (select o.add_time,og.id,(CASE WHEN og.proct_id>1 THEN (select id from proct where proct.id=og.proct_id and proct.is_show=1) ELSE o.add_time END) as proct_id from order as o left join order_goods as og on o.order_id=og.order_id order by o.add_time desc limit 9999) table1  where proct_id is not null group by proct_id order by add_time desc

方法3:使用isfull()函數 ,思路和方法2一樣,都是判斷欄位值是否為空,若是空值先賦一個臨時值後分組

需要注意的是,isfull只能用於判斷是否為null,若值是0無效(見圖3 圖4)