一些Oracle SQL語句的例子<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
例子所是用的數據庫表。(這些表不包括任何約束,僅用於SELECT連接查詢)
CREATE TABLE xapp_classes(
id NUMBER(4),
name VARCHAR2(20)
);
CREATE TABLE xapp_students(
id NUMBER(4),
classid NUMBER(4),
name VARCHAR2(20)
age NUMBER(3),
);
CREATE TABLE xapp_courses(
id NUMBER(4),
name VARCHAR2(20)
);
CREATE TABLE xapp_students_courses(
studentid NUMBER(4),
courseid NUMBER(4),
points NUMBER(3)
);
CREATE TABLE xapp_grades(
name VARCHAR2(4),
minp NUMBER(3),
maxp NUMBER(3)
);
xapp_grades表所使用的數據
INSERT INTO xapp_grades VALUES('A', 90, 100);
INSERT INTO xapp_grades VALUES('B', 80, 89);
INSERT INTO xapp_grades VALUES('C', 70, 79);
INSERT INTO xapp_grades VALUES('D', 60, 69);
INSERT INTO xapp_grades VALUES('F', 0, 59);
等值連接
SELECT s.name "Student",
c.name "Course"
FROM xapp_students s,
xapp_courses c,
xapp_students_courses sc
WHERE s.id = sc.studentid
AND sc.courseid = c.id
不等值連接
SELECT s.name "Student",
c.name "Course",
g.name "Grade"
FROM xapp_students s,
xapp_courses c,
xapp_students_courses sc,
xapp_grades g
WHERE s.id = sc.studentid
AND sc.courseid = c.id
AND sc.points BETWEEN g.minp AND g.maxp
-- 通過xapp_grades表輸出分數對應的等級
自連接
SELECT DISTINCT s1.name
FROM xapp_students s1,
xapp_students s2
WHERE s1.name = s2.name
AND s1.id <> s2.id
外連接
SELECT s.name "Student",
NVL(c.name, 'No Class') "Class"
FROM xapp_students s,
xapp_classes c
WHERE s.classid = c.id(+)
分組查詢
語法:
SELECT fields FROM table
WHERE expression
GROUP BY field
HAVING expression
fields中只能有已分組字段與表達式和聚合函數
WHERE的判斷條件不能有已分組的內容
HAVING的判斷條件只能包括已分組的內容
Example 1
SELECT classid, COUNT(*)
FROM xapp_students
GROUP BY classid
Example 2
SELECT g.name "Grade",
COUNT(*) "Student Count"
FROM xapp_students_courses sc,
xapp_grades g
WHERE sc.points BETWEEN g.minp AND g.maxp
GROUP BY g.name
Example 3
SELECT (TRUNC(points/10)*10)||'-'||( TRUNC(points/10)*10+9) "Point",
COUNT(*) "Student Count"
FROM xapp_students_courses
GROUP BY TRUNC(points/10)
-- 按points分數段分組
-- 通過表達式分組,SELECT子句中只能出現分組的表達式
Example 4
SELECT NVL(c.name, 'No Class') "Class Name",
COUNT(*) "Student Count"
FROM xapp_students s,
xapp_classes c
WHERE s.classid = c.id(+)
GROUP BY c.name
Example 5
SELECT
NVL((SELECT c.name FROM xapp_classes c
WHERE c.id=s.classid),'No Class') "Class Name",
COUNT(*) "Student Count"
FROM xapp_students s
GROUP BY classid
ORDER BY COUNT(*)
-- 與前一個例子相比,這裏通過NUMBER類型的字段classid分組,
-- 而沒用通過CHAR類型字段分組
-- 在SELECT子句中使用自查詢
-- 效率與前一個例子相比?
Example 6
SELECT age, COUNT(*)
FROM xapp_students
GROUP BY age
HAVING COUNT(*) > 2
ORDER BY age
-- HAVING子句的使用
子查詢的2個例子
SELECT * FROM xapp_students
WHERE age > (SELECT AVG(age) FROM xapp_students)
SELECT name
FROM xapp_students
WHERE id IN (SELECT DISTINCT studentid
FROM xapp_students_courses
WHERE points IS NOT NULL)
ROWNUM
-- ROWNUM與ORDER BY同時存在時,先計算ROWNUM,再進行排序
-- (與SQL Server的TOP *不同)
-- 需要嵌套1層子查詢實現該功能
-- 錯誤,不能選擇出按name排序前4的記錄
SELECT id, name
FROM xapp_students
ORDER BY name
WHERE ROWNUM <= 4
-- 正確
SELECT id, name
FROM (SELECT id, name
FROM xapp_students
ORDER BY name)
WHERE ROWNUM <=4
選擇第2條到第4條記錄
SELECT id, name
FROM (SELECT id, name, ROWNUM rn
FROM xapp_students
WHERE ROWNUM <= 4)
WHERE rn >= 2
選擇排序後第2條到第4條記錄
SELECT id, name
FROM (SELECT id, name, ROWNUM rn
FROM (SELECT id, name
FROM xapp_students
ORDER BY name)
)
WHERE rn BETWEEN 2 AND 4