--設置日期格式
alter session set nls_date_format = 'yyyy-mm-dd';
--1.
--查詢某些字段
select customer_id,
first_name,
last_name,
dob,
phone
from customers;
--查詢所有列
select *
from customers;
--過濾行
select *
from customers
where customer_id = 2;
--行標識符,僞列:rowid
select rowid,
customer_id
from customers;
--行號,僞列:rownum
select rownum,
customer_id
from customers;
--2.算術運算
select 2 * 6 from dual;
--日期運算
select to_date('2007-05-08'),
to_date('2007-05-08') + 2 ,
to_date('2007-05-08') - 8,
to_date('2007-05-08') - to_date('2007-04-08')
from dual;
--字符串連接運算
select first_name || ' ' || last_name
from customers;
--dual表包含一個varchar2數據類型的列,列名爲dummy,而且只包含一行,值爲x
desc dual;
select * from dual;
--列運算
select name,
price,
price + 2,
price * 10 + 2
from products;
--注意運算符的優先級,()可用於指定操作符的執行順序
select 10 * 12 / 3 - 1,
10 * (12 / 3 - 1)
from dual;
--3.列別名
select price * 2 double_price, --列別名會變爲大寫
price * 2 + 1 as "double price", --使用雙引號後,可以保持列別名的大小寫、空格
price * 4 as double_price --可以使用可選的關鍵字as
from products;
--4.空值
--查詢dob列爲空的數據
select customer_id,
first_name,
last_name,
dob
from customers
where dob is null;
--查詢dob列爲非空的數據
select customer_id,
first_name,
last_name,
dob
from customers
where dob is not null;
--nvl函數:轉換空值爲一個可以理解的值
select customer_id,
first_name,
last_name,
nvl(dob,'2100-01-01') as dob
from customers
where dob is null;
--5.去除重複值
select customer_id
from purchases;
select distinct customer_id
from purchases;
select unique customer_id
from purchases;
--6.比較運算
select *
from customers
where customer_id = 2
select *
from customers
where customer_id <> 2
select *
from products
where rownum <= 3
--查詢customer_id大於2,3,4中任意一個的記錄
select *
from customers
where customer_id > any(2,3,4);
--查詢customer_id比2,3,4都大的記錄
select *
from customers
where customer_id > all(2,3,4)
--7.SQL操作符
--like操作符
select *
from customers
where first_name like '_o%' --以任意一個字符開頭,第二個字符爲o,的字符串
select *
from customers
where first_name not like '_o%' --排除,以任意一個字符開頭第二個字符爲o的字符串
--如果需要對一個字符串中的下劃線或%進行匹配時,可以通過escape選項標識這些字符
--escape選項中的反斜槓表示了前面like的字符串中反斜槓後的字符只是普通字符,而不是特殊字符
select name
from promotions
where name like '%\%%' escape '\';
--這裏不再用反斜槓\來做轉義字符,而是通過一個字符Z來表示轉義字符,表示這個字符後的字符是個普通字符
select name
from promotions
where name like '%Z%%' escape 'Z';
--這裏會報錯,因爲一旦把字符Z作爲轉義字符,那麼在like的模式字符串中使用這個Z這個字符就必須按規定,
--後面必須跟上一個字符,否則就會報錯:ORA-01424: 轉義符之後字符缺失或非法
select name
from promotions
where name like '%Z%%Z' escape 'Z';
--這裏不會報錯,因爲轉義字符後面包含了一個字符,雖然這個字符也是轉義字符,但後一個轉義字符z,
--被前面的轉義字符轉義了,也就是一個普通的字符,也就是可以匹配以Z字符結尾的記錄
select name
from promotions
where name like '%Z%%ZZ' escape 'Z';
--這裏也不會報錯,而且能返回記錄,ZZ%中第一個Z是轉義字符,把第二個Z轉義爲普通字符,
--所以後面的%還是一個特殊字符,表示匹配0-N個任意字符,所以會返回包含了字符%,同時也包含了Z字符的數據
select name
from promotions
where name like '%Z%%ZZ%' escape 'Z';
--in操作符
select *
from customers
where customer_id in (2,3,4);
--1,5不是2,3,4,但是1,5是不是null,是無法判斷的,總會返回false,所以返回0條記錄。
--就是如果在not in 的列表中有null值,那麼最後不會返回任何結果集。
select *
from customers
where customer_id not in (2,3,4,null);
--between操作符
select *
from customers
where customer_id between 2 and 4
--邏輯操作符:and 和 or
select *
from customers
where customer_id >= 2 and dob > '1971-01-01'
select *
from customers
where customer_id >= 2 or dob > '1970-01-01'
--注意and和or的優先級,and優於or
select *
from customers
where dob > '1970-01-01'
or customer_id < 2
and phone like '%1211'
--8.排序
--通過order by關鍵字指定排序的列和順序(asc升序,desc降序)
--排序的列可以不包含在select字句的字段列表中
select customer_id,
dob,
phone
from customers
order by first_name asc,last_name desc
--不用指定列名,而是直接通過列在結果集中的順序指定
select customer_id,
first_name,
last_name,
dob,
phone
from customers
order by 2 asc,3 desc
--9.表關聯
--9.1 適用於Oracle Database 8i及更低版本,應該使用SQL/86標準語法。
--內連接
select p.name,
pt.name
from products p,product_types pt
where p.product_type_id = pt.product_type_id
order by p.name
--左外連接
--以products爲主表,會返回products所有的記錄,包括product_type_id爲null的記錄
--以product_types爲輔表,對應的關聯字段要加上外連接操作符:(+)
select p.name,
pt.name
from products p,product_types pt
where p.product_type_id = pt.product_type_id(+)
--右外連接
--以product_types爲主表,會返回所有產品類型,
--以products爲輔表,對應的關聯字段要加上外連接操作符:(+)
select p.name,
pt.name
from products p,product_types pt
where p.product_type_id(+) = pt.product_type_id
--外連接的限制
--不能在連接的兩端使用oracle的連接操作符
/*
錯誤報告:
SQL 錯誤: ORA-01468: 一個謂詞只能引用一個外部聯接的表
*/
select p.name,
pt.name
from products p,product_types pt
where p.product_type_id(+) = pt.product_type_id(+)
--不能同時使用一個外連接條件和另外一個使用or操作符的連接條件
/*
錯誤報告:
SQL 錯誤: ORA-01719: OR 或 IN 操作數中不允許外部聯接運算符 (+)
*/
select p.product_type_id,pt.product_type_id,
p.name,
pt.name
from products p,product_types pt
where p.product_type_id(+) = 1
or p.product_type_id(+) = pt.product_type_id;
--需要注意的是,但是下面的查詢確沒有報錯,可以正常運行
select p.product_type_id,pt.product_type_id,
p.name,
pt.name
from products p,product_types pt
where p.product_type_id(+) = pt.product_type_id
and p.product_type_id(+) in (1,2,3,4);
--笛卡爾積
select p.product_type_id,
pt.product_type_id
from products p,product_types pt
--自連接,也就是一個表和自己關聯
--下面的語句只會出現 有上級的人員
select e.first_name || ' ' || e.last_name || ' works for ' ||
m.first_name || ' ' || m.last_name
from employees e,employees m
where e.manager_id = m.employee_id
order by e.first_name;
--顯示所有的人員,不管是否有上級
--從下面的語句可以看出,在oracle中字符串與空值連接,還是會返回字符串
select e.first_name || ' ' || e.last_name || ' works for ' ||
m.first_name || ' ' || m.last_name,
e.first_name || ' ' || e.last_name || ' works for ' ||
nvl(m.last_name,'the shareholders')
from employees e,employees m
where e.manager_id = m.employee_id(+)
order by e.first_name;
--9.2 適用於Oracle Database 9i及更高版本,可以使用SQL/92標準語法。
--如果關聯字段的名稱是相同的,可以通過using關鍵字來簡化關聯條件
--內連接
select p.name,
pt.name
from products p
inner join product_types pt
on p.product_type_id = pt.product_type_id
order by p.name
--通過using來簡化
select p.name,
pt.name
from products p
inner join product_types pt
using(product_type_id)
order by p.name
select p.name,
pt.name,
p.product_type_id --SQL 錯誤: ORA-25154: USING 子句的列部分不能有限定詞
from products p
inner join product_types pt
using(product_type_id)
order by p.name
select p.name,
pt.name,
product_type_id
from products p
inner join product_types pt
using(p.product_type_id) --SQL 錯誤: ORA-01748: 此處只允許簡單的列名
order by p.name
--左外連接
--以products爲主表,會返回products所有的記錄,包括product_type_id爲null的記錄
--以product_types爲輔表.
select p.name,
pt.name
from products p
left join product_types pt
on p.product_type_id = pt.product_type_id
--右外連接
--以product_types爲主表,會返回所有產品類型,
--以products爲輔表
select p.name,
pt.name
from products p
right join product_types pt
on p.product_type_id = pt.product_type_id
--全外連接
select p.name,
pt.name
from products p
full join product_types pt
on p.product_type_id = pt.product_type_id
--笛卡爾積
select p.product_type_id,
pt.product_type_id
from products p
cross join product_types pt
--自連接,也就是一個表和自己關聯
--下面的語句只會出現 有上級的人員
select e.first_name || ' ' || e.last_name || ' works for ' ||
m.first_name || ' ' || m.last_name
from employees e
inner join employees m
on e.manager_id = m.employee_id
order by e.first_name;
--顯示所有的人員,不管是否有上級
--從下面的語句可以看出,在oracle中字符串與空值連接,還是會返回字符串
select e.first_name || ' ' || e.last_name || ' works for ' ||
m.first_name || ' ' || m.last_name,
e.first_name || ' ' || e.last_name || ' works for ' ||
nvl(m.last_name,'the shareholders')
from employees e
left join employees m
on e.manager_id = m.employee_id
order by e.first_name;