Oracle Database 11g SQL 開發指南學習筆記:從數據庫中檢索數據

 

--設置日期格式
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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章