茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1670047 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_00028.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

DB研討會 : [轉貼]MSSQL Join總結

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]MSSQL Join總結
MSSQL Join總結

SQL 之JOIN 用法完全版一、各種JOIN的含義SQL中大概有這麼幾種JOIN:
cross join
inner join
left outer join
right outer join
full outer join

首先都是基於cross join(笛卡爾乘積),然後是inner join,在笛卡爾乘積的結果集中去掉不符合連接條件的行。
left outer join 是在inner join的結果集上加上左表中沒被選上的行,行的右表部分每個字段都用NUll填充。
right outer join 是在inner join的結果集上加上右表中沒被選上的行,行的左表部分全用NULL填充。
outer的意思就是"沒有關聯上的行"。

二、舊式寫法和標準寫法:
1、INNER Join code as the following:
Select * from A a, B b where a.categoryID = b.categoryID;

Equals:
Select * from A a inner join B b on a.categoryID = b.categoryID;

2、OUTER Join code as the following:
select * from A a full(left/right) outer  join B b  on a on a.categoryID = b.categoryID;

Equals:
Select * from A a, B b where a.categoryID *=  b.categoryID;Select * from A a, B b where a.categoryID =*  b.categoryID;


三、例子Table A have 12( 8+4) entries, 8 entries have valid relation with BTable B have 80(77+3) entries , 77 entries have valid relation with A. then the return amount of join is :
cross join : 12*80
inner join : 77
full outer join : 77+4+3
left outer join: 77 + 4
right outrer join: 77 + 3

join 方式
(1) cross join
參與select語句所有表的的所有行的笛卡爾乘積
      select au_lname ,title from authors cross join  titiles

outer join 對參與join的兩個表有主從之分,處理方式以主表的每條數據去match 從屬表的列,合乎條件的數據是我們所要的答案,不合乎條件的也是我們要的答案,只不過哪些從屬表選取的列將被添上null。
(2) left join
左邊的為主表,右邊為從屬表
     select a.cust_id ,b.order_date,b.tot_ant from customer a left join sales b
       on (a.cust_id =b.cust_id and b.order_date>''1996/10/15'')

可以寫為
     select a.cust_id,b.order_date,b.tot_ant from custom a
        left join (select * from sales where order_date>''1996/10/15'') b
        on a.cust_id =b.cust_id

(3) right join
左邊的表為從屬表,右邊的表為主表
(4) self join
self join 常用在同一表內不同數據間對同一列的比較
     select a.emp_no,a.emp_name,b.emp_no,b.emp_name,a.date_hired from employee a
        join employee b on (a.emp_no!=b.emp_no and a.date_hired=b.date_hired)
            order by a.date_hired

這樣會重複數據,只要加上一句
and a.emp_name>b.emp_name

(5) full join
不僅列出符合條件的數據,兩邊未符合join條件的數據也會一併列出。哪些未符合join條件的數據如果在select列中無法得到對應的值則填上null
    select a.cust_id,b.tot_amt from customer a full join sales b
         on a.cust_id=b.cust_id

有表
     id   ic  name  amount
      I    *        *
      c
      i
      c
      i
      i

要求結果為
    ic  name  amount  ic   name  amount
    i                         c
    i                         c
    i
    i

  select aaa.*,bbb.*  from (select (select count(id) from aa as b where (b.id<a.id) and (ic=''i'')) as newid, *
        from aa a where ic=''i'') aaa full join
         (select (select count(id) from aa as b where b.id<a.id and ic=''c'') as newid,* from
             aa a where ic=''c'') bbb on aaa.newid=bbb.newid order by aaa.name

6.使用 HASH 和 MERGE 聯接提示
此示例在 authors、titleauthors 和 titles 表之間建立三表聯接,以生成一個作者及其著作的列表。查詢優化器使用 MERGE 聯接將 authors 和 titleauthors (A x TA) 聯接在一起。然後,將 authors 和 titleauthors MERGE 聯接 (A x TA) 的結果與 titles 表進行 HASH 聯結以生成 (A x TA) x T。
重要 指定聯接提示後,要執行 INNER JOIN 時 INNER 關鍵字不再為可選,而必須顯式說明。
  USE pubs
  SELECT SUBSTRING((RTRIM(a.au_fname) + '' '' + LTRIM(a.au_lname)), 1, 25)
     AS Name, SUBSTRING(t.title, 1, 20) AS Title
     FROM authors a INNER MERGE JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER HASH JOIN titles t
      ON t.title_id = ta.title_id
     ORDER BY au_lname ASC, au_fname ASC

下面是結果集:
  Warning: The join order has been enforced because a local join hint is used.
  Name                      Title
  ------------------------- --------------------
  Abraham Bennet            The Busy Executive''s
  Reginald Blotchet-Halls   Fifty Years in Bucki
  Cheryl Carson             But Is It User Frien
  Michel DeFrance           The Gourmet Microwav
  Innes del Castillo        Silicon Valley Gastr
  ...                    ...
  Johnson White             Prolonged Data Depri
  Akiko Yokomoto            Sushi, Anyone?

  (25 row(s) affected)

                      dbo.CheckPerson.checkPersonID = dbo.Employee.employeeID INNER JOIN
                      dbo.Employee AS Employee_1 ON dbo.RequirePlan.establishPersonID = Employee_1.employeeID AND
                      dbo.CheckPerson.checkPersonID = Employee_1.employeeID

Employee_1前邊沒有dbo.

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/luxuejuncarl/archive/2006/12/31/1470612.aspx
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼][MySQL] outer join 使用
之前我遇到問題,有兩個表格 a 跟 b,分別利用 id 當作連接,當你使用 where a.id = b.id 的時候,當 b 資料表沒有對應到的時候,撈出來的資料就會少一筆,問題如下

: 想請教各位大大,
: 如果我現在有兩個table t1,t2
: Table t1:
: uid INT
: name NCHAR(10)
: Table t2:
: uid INT
: t1_id INT 參考到t1.uid
: 我下一個SQL query:
: SELECT t1.name, COUNT(t2.uid)
: FROM t1,t2
: WHERE t2.t1_id=t1.uid
: GROUP BY t1.name
: 這樣會計算出每個t1.name項目在t2中所出現的次數。
: 但是如果次數為零時就不會顯示出來。
: 想請教大家,怎樣修改可以讓次數為零的t1.name也顯示出來呢?

解決方法:就是利用 outer join
$sql = "SELECT t1.t_name, count(t2.uid) as aa 
FROM " . $xoopsDB->prefix('teacher') . " as t1 
LEFT OUTER JOIN " . $xoopsDB->prefix('student') . " as t2 
on t1.tid = t2.st_teacher 
group by t1.t_name";




原文出處:[MySQL] outer join 使用 | 小惡魔 - 電腦技術 - 工作筆記 - AppleBOY
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼][MySQL]left, right, inner, outer join 使用方法
[MySQL]left, right, inner, outer join 使用方法
Jan 24th, 2009 by appleboy

最近在高雄面試的時候,被問到的資料庫問題,什麼是 left join,out join,inner join,其實這些都是寫基本 SQL 語法需要知道的,當然我比較少用到 out join,不過還是要知道一下比較好喔,底下來說明一下這些,整理一些心得

表格 test1 資料表


表格 test2 資料表


首先大概是了解 inner 跟 outer 的差別,初學者大概都會使用 inner 這也是我們常常在用的 SQL,inner 就是 join 兩個資料表只顯示匹對的資料,另外一種 outer 就是不管是否有匹對,都會將資料顯示出來,又分為 LEFT, RIGHT, FULL join。

join 總共分為六種
Inner Join
Natural Join
Left Outer Join
Right Outer Join
Full Outer Join
Cross Join

1. Inner Join
--
-- 這算是最普通的 join 方法
--
SELECT a.*, b.* FROM `test1` AS a, `test2` AS b WHERE a.id = b.id

2. Natural Join
--
-- 利用兩資料表相同欄位,自動連接上
--
SELECT a.*, b.* FROM `test1` AS a NATURAL JOIN `test2` AS b

3. Left, Right join
--
-- 這兩個其實是相同的,left join 就是顯示左邊表格所有資料,如果匹對沒有的話,就是顯示 NULL right 則是相反
--
SELECT a.*, b.* FROM `test1` AS a LEFT JOIN `test2` AS b ON a.id = b.id

4. Full Outer Join
這個可以利用 SQL UNION 處理掉,這只是聯集 Left 跟 Right

5. Cross Join
在 MySQL 語法裡面,它相同於 INNER Join,但是在標準 SQL 底下,它們不盡相同
SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

同等於
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

取一段 MySQL 官網的文字:
In MySQL, CROSS JOIN is a syntactic equivalent to INNER JOIN (they can replace each other).
In standard SQL, they are not equivalent.
INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise.



原文出處:[MySQL]left, right, inner, outer join 使用方法 | 小惡魔 - 電腦技術 - 工作筆記 - AppleBOY
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]一些來自 MySql 官網上的討論範例,超實用!
一些來自 MySql 官網上的討論範例,超實用!

Below is an example of how to left-join multiple tables independently.
SELECT ...
FROM table 1
LEFT JOIN table 2 on (table1.id = table2.id)
LEFT JOIN table 3 on (table1.id2 = table3.id2)
LEFT JOIN table 4 on (table1.id3 = table4.id3)


This is an example of using a left to get lookup values from a table twice. The reason that an outer join was used instead of an inner join, was that in this case, there may be values that are null inside of the degree table.
SELECT d.degDegId, m1.majDescription AS major_1, m2.majDescription AS major_2
FROM degree AS d
LEFT OUTER JOIN major AS m1
ON d.degMajor1 = m1.majMajId
LEFT OUTER JOIN major AS m2
ON d.degMajor2 = m2.majMajId


You can emulate FULL OUTER JOIN using UNION (from MySQL 4.0.0 on):
with two tables t1, t2:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

with three tables t1, t2, t3:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
LEFT JOIN t3 ON t2.id = t3.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
LEFT JOIN t3 ON t2.id = t3.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
RIGHT JOIN t3 ON t2.id = t3.id


The result of a full outer join betwee tables A and B includes:
- rows from the result of the inner join
- rows from A that don't have corresponding rows in B
- rows from B that don't have corresponding rows in A

Formally, the corresponding SQL statement looks like this:
SELECT *
FROM A JOIN B ON A.id = B.id
UNION ALL
SELECT *
FROM A LEFT JOIN B ON A.id = B.id
WHERE B.id IS NULL
UNION ALL
SELECT *
FROM A RIGHT JOIN B ON A.id = B.id
WHERE A.id IS NULL

Due to the fact that the first union represents a left outer join, the statement can be simplified:
SELECT *
FROM A LEFT JOIN B ON A.id = B.id
UNION ALL
SELECT *
FROM A RIGHT JOIN B ON A.id = B.id
WHERE A.id IS NULL



原文出處:MySQL :: MySQL 5.5 Reference Manual :: 13.2.9.2 JOIN Syntax
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Oracle PL/SQL SELECT 的 OUT JOIN (+) 用法
對於 Oracle Out Join (+) 的用法,是將 (+) 放置在可能沒有資料的 Table 一方,

範例如下 :
-- 建立 Temp Table
create table tom1(
  aa number
, bb varchar2(100)
);

create table tom2(
  aa number
, cc varchar2(100)
);

create table tom3(
  cc varchar2(100)
, dd varchar2(100)
);

-- 建立 Temp Data
insert into tom1 values( 1, 'A' );
insert into tom1 values( 2, 'B' );
insert into tom1 values( 3, 'C' );
insert into tom1 values( 4, 'D' );
insert into tom1 values( 5, 'E' );

insert into tom2 values( 1, 'I' );
insert into tom2 values( 3, 'J' );
insert into tom2 values( 5, 'K' );

insert into tom3 values( 'J', 'JJJ' );
insert into tom3 values( 'K', 'KKK' );

commit;

-- 查詢 tom1 有, 且 tom2 也要有的資料, 同時也抓出 tom2 在 tom3 的 dd 欄位值
select t1.aa
     , t1.bb
     , t2.cc
     , t3.dd
  from tom1 t1
     , tom2 t2
     , tom3 t3
 where t1.aa = t2.aa
   and t2.cc = t3.cc(+)  -- (+) 放置在可能沒有資料的 Table 一方
 order by t1.aa;

-- 結果
AA     BB     CC     DD
------ ------ ------ ------
1      A      I      (null)
3      C      J      JJJ
5      E      K      KKK

-- 查詢 tom1 有, 但 tom2 可有可無的資料, 同時也抓出 tom2 在 tom3 的 dd 欄位值
select t1.aa
     , t1.bb
     , t2.cc
     , t3.dd
  from tom1 t1
     , tom2 t2
     , tom3 t3
 where t1.aa = t2.aa(+)  -- (+) 放置在可能沒有資料的 Table 一方
   and t2.cc = t3.cc(+)  -- (+) 放置在可能沒有資料的 Table 一方
 order by t1.aa;

-- 結果
AA     BB     CC     DD
------ ------ ------ ------
1      A      I      (null)
2      B      (null) (null)
3      C      J      JJJ
4      D      (null) (null)
5      E      K      KKK


原文出處:昭佑.天翔: Oracle PL/SQL SELECT 的 OUT JOIN (+) 用法
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]SQL Join 的觀念

[SQL]Join的觀念

[SQL]Join的觀念

前言

在位置上很常聽到人家討論SQL的時候,Join來Join去,害我每次都會回頭(因為聽起來實在很像在叫我的名字)。

小的自認為DB與SQL的功力,一向很薄弱。
而training新人時,第一個要解釋table與table之間關係,通常也是會講到join。

我雖然大概知道join是怎麼一回事,不過有時候解釋起來,看新人一臉疑惑的表情,也是讓我頗受傷的。

所以,上次看了呂老師書上的一張圖,
真的深深覺得一張圖加兩張table的範例資料,勝過千言萬語啊。

What is join?

Join,通常稱做交集,而交集是什麼呢?望文生義,看圖說故事,各位看官就會瞭解了。


join


這張圖,解釋了兩張表之間的關係。

兩張table,我們分別定義為Left table跟Right table。Left就是被交集的table (要稱做資料集合也可以),Right就是拿來交集的table。
就像A x B = C,我們稱A為被乘數,B為乘數,一樣的意思。

比較常看到的,Left table,就是Select * from [table1] ,這個from的table。
Right table,則是被join的那一張table,
例如

Select * from [table1]
Left join [table2] on [table1].fk=[table2].pk


在這例子,table2就是圖裡面的Right table。

而兩張table join的條件,也就是他們是靠什麼來做交集的,就是on後面的 [table1].fk=[table2].pk。
交集的條件不一定只有一個,Left table與Right table的交集後的結果,也有可能是空集合,也就是無符合的資料。

好,接著我們來給兩張表一些資料。

Table1:


PK FK
1 a1
2 a2
3 a3


Table2:

PK Description
a2 a2很棒
a3 a3很棒
a4 a4很棒

當我們現在join的條件是Table1.FK與Table2.PK。

  1. Inner Join,就代表Table1與Table2兩者,完全符合交集條件的資料集合。
    也就是上面圖裡面,兩個圈圈共同圈起來的那個部分,
    SQL的範例,通常inner join我們會直接寫
    Table1_PK Table1_FK Table2_Description
    2 a2 a2很棒
    3 a3 a3很棒
    • Select * from table1, table2
      Where table1.FK=table2.PK


      Inner Join代表的是兩個table共同的部分才要篩選出來,所以誰是Left,誰是Right其實沒有多大分別。

      於是,以我們的範例資料來說,這個例子會撈出
  2. 除了Inner以外,當然就是Outer了。
    Outer又分兩種,一種是左邊的Outer,一種是右邊的Outer。
    什麼叫做左邊的Outer,在我們的圖裡面,就是左邊的圈圈全都要出來,而符合交集條件的右邊圈圈,資料也要帶出來。
    Table1_PK Table1_FK Table2_Description
    1 null null
    2 a2 a2很棒
    3 a3 a3很棒

    Table1_PK Table2_PK Table2_Description
    2 a2 a2很棒
    3 a3 a3很棒
    null a4 a4很棒
    • Left join的SQL如下:
      Select * from table1
      Left outer join table2 on table1.FK = table2.PK


      在這例子,代表了table1就是我們的Left table,所以Left outer join後,table1所有資料都應該顯示出來,
      而符合table1.FK = table2.PK條件的資料,應該會帶出Table2的相關欄位資料。

    • Right join的SQL如下:
      Select * from table1
      Right outer join table2 on table1.FK = table2.PK


      在這例子,table2代表我們的Right table,所以Table2所有資料應該顯示出來,並且符合交集條件的資料,應該有table1的欄位資料。


另外要提醒的,outer是可以省略的。而在Join裡面,Where條件扮演著什麼角色?
其實Where的條件,是用來限制Left table與Right table的Scope的。

所以where與join可以說毫無關係,因為是用來分別定義table的篩選條件,而非交集的條件。

希望不會在有朋友搞不清楚,到底什麼條件要放在join的on裡面,
什麼條件該放在where裡面。

用這張圖去思考一下,會幫您釐清許多的問題。

結論

  1. 上述的所有table,只是一種資料集合。也就是代表,它可以是另外一個子查詢後的結果。
  2. Left與Right的定義,則是被乘數與乘數的分別。
  3. Where只是篩選條件,拿來限制Left table與Right table的Scope。
  4. Inner Join沒有左右的差異,所以可以直接用兩張表的一個where 條件來表示,當然您要寫成inner join的表示法也會更符合這張圖的意義喔。
  5. Outer Join的Outer可以省略,但Left或Right則不能省略。

複雜或多層的Join,只是像寫程式剝洋蔥或穿衣服一樣,可以想像一行一行的join下來,每次都只有一個被乘數和乘數在做交集而已。
就像
a1 x a2 x a3 x a4,您會先計算a1 x a2後,再 x a3,之後的結果再 x a4一樣。

補充(2011/07/20):很讚的說明: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html



原文出處:[SQL]Join的觀念 | In 91 - 點部落
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]SQL inner join、full out join、left join 的觀念

inner join、full out join、left join

摘要:inner join、full out join、left join

圖片來源為FB的MSDN小編

由於在網路上討論join的文章雜亂煩多,我是有看沒有懂,

故,我還是自己親自跑實例比較明瞭(自己親自跑一遍就通了)。

 

一、一開始先建立資料



CREATE TABLE [dbo].[table_a]
(
[id_a] [FLOAT] NULL,
[name_a] [NVARCHAR](50) NULL
)
ON [PRIMARY]
go
CREATE TABLE [dbo].[table_b]
(
[id_b] [FLOAT] NULL,
[name_b] [NVARCHAR](50) NULL
)
ON [PRIMARY]
go
--dbo.Table_a
INSERT dbo.Table_a VALUES (1, N'a')
INSERT dbo.Table_a VALUES (2, N'b')
INSERT dbo.Table_a VALUES (3, N'c')
INSERT dbo.Table_a VALUES (4, N'd')
--dbo.Table_b
INSERT dbo.Table_b VALUES (1, N'aa')
INSERT dbo.Table_b VALUES (2, N'bb')
INSERT dbo.Table_b VALUES (5, N'cc')
INSERT dbo.Table_b VALUES (6, N'dd')

 

二、先列出table_a與table_b的資料



select * from table_a



select * from Table_b

 

三,主要join方式 

個人製作的註記簡圖

 

1、inner join



select * from Table_a
join Table_b on Table_a.id_a = Table_b.id_b



select * from Table_a
inner join Table_b on Table_a.id_a = Table_b.id_b

的結果是一樣的

還有一個語法跟inner join是蠻相似的,就是NATURAL JOIN,

其兩資料表之間同名的欄位會被自動結合在一起。

不過在SQL SERVER則是不支援這種語法,如想了解請參考

NATURAL JOIN 關鍵字 (SQL NATURAL JOIN Keyword) - 自然連接

 

2.1、full outer join等於full join



select * from Table_a
full join Table_b
on Table_a.id_a = Table_b.id_b

 

2.2、full outer join but a.Key is null or b.Key is null



select * from Table_a
full outer join Table_b
on Table_a.id_a = Table_b.id_b
where Table_a.id_a is null or Table_b.id_b is null

 

3.1、left outer join等於left join



select * from Table_a
left join Table_b on Table_a.id_a = Table_b.id_b

 

3.2、left outer join but b.Key is null



select * from Table_a
left outer join Table_b on Table_a.id_a = Table_b.id_b
where Table_b.id_b is null

 

4.1、right outer join等於right join



select * from Table_a
right join Table_b on Table_a.id_a = Table_b.id_b

 

4.2、right outer join but a.Key is null



select * from Table_a
right outer join Table_b on Table_a.id_a = Table_b.id_b
where Table_a.id_a is null

 

5、笛卡爾積、交叉合併cross join



select * from Table_a ,Table_b

 

結論:感覺使用圓餅來解說似乎也不是那麼直覺好理解,也有人用較直覺的資料列方圖來表示,

個人覺得使用三度空間的立體圖來表示會不會好一點。

 

參考資料:

A Visual Explanation of SQL Joins

[SQL]Join的觀念


原文出處:inner join、full out join、left join | 阿沙布魯 - 點部落
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|