[VB.NET] พื้นฐานของ SQL Joins ระหว่างตารางข้อมูล 2 ตาราง
http://www.g2gnet.com/webboard/images/vbnet/DBVBJoin.pngในบทความนี้ แอดมินจะจำลอง เพื่อแสดงให้เห็นถึงการจอย (JOIN) หรือเชื่อมความสัมพันธ์ระหว่างตารางข้อมูล 2 ตารางเข้าหากัน ด้วยวิธีการกระจายข้อมูลออกให้เห็นในรูปแบบของเซ็ต (SET) โดยใช้ไฟล์ฐานข้อมูล Microsoft Access มาเป็นตัวอย่าง ซึ่งมันก็ใช้ไวยากรณ์ที่คล้ายๆกันฐานข้อมูลตัวอื่นๆนั่นแหละครับท่านผู้ชม ...
http://www.g2gnet.com/webboard/images/vbnet/dbtable.png
สมมุติชื่อเล่นตาราง A คือ ตารางนักศึกษา (Student)
สมมุติชื่อเล่นตาราง B คือ ตารางอาจารย์ที่ปรึกษา (Advisor)
ในการแจกแจงสมาชิกท่านต้องกลับไปเปิดจากคณิตศาสตร์ ม.4 เทอม 1 ดูกันเองครับ ... สรุปให้สั้นๆ คือ ...
- Student 1 และ 9 มี Advisor 1 เป็นที่ปรึกษา ส่วน Student 5, 7, และ 10 มีอาจารย์ Advisor 3 เป็นที่ปรึกษา
- Student 2 และ 4 ไม่มีความสัมพันธ์ของตารางข้อมูลกับอาจารย์ที่ปรึกษาคนใด และ Advisor 5 ก็ไม่ได้เป็นที่ปรึกษาให้แก่นักศึกษาคนใด พวกนี้จัดว่าอยู่นอกเหนือความสัมพันธ์กัน
หมายเหตุ: AdvisorFK คือคีย์รองจากตาราง Student (เพราะคีย์หลักตารางนี้คือ StudentPK) ที่เชื่อมกลับไปหาคีย์หลัก AdvisorPK ซึ่งความหมายก็คือตัวเดียวกันนั่นแหละครับ
กรณี Inner Join (หรือ อินเตอร์เซคชัน Intersection) ...
http://www.g2gnet.com/webboard/images/vbnet/DBInner.png
พบว่าตาราง A และ B หากมีความสัมพันธ์กันแบบไร้เงื่อนไขก็จะมีสมาชิกอยู่ 5 รายการ ซึ่งกรณีของ Inner Join นี้เราต้องใช้งานบ่อยมากSELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student INNER JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentPKตาราง A JOIN กับตาราง B เมื่อคีย์รอง AdvisorFK มีค่าเท่ากับคีย์หลัก AdvisorPK
http://www.g2gnet.com/webboard/images/vbnet/VBInner.png
ความหมายคือ รายชื่อของนักศึกษาที่มีอาจารย์เป็นที่ปรึกษาเรียบร้อย
กรณี Left Join ...
http://www.g2gnet.com/webboard/images/vbnet/DBLeft.png
ประกอบไปด้วยสมาชิก 7 รายการ
SELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student LEFT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentPKhttp://www.g2gnet.com/webboard/images/vbnet/VBLeft.png
Student 2 ต้องให้ Advisor 8 เป็นที่ปรึกษา แต่ทว่า Advisor 8 ไม่มีรายชื่อปรากฏอยู่ในตาราง Advisor (กรณี Student 4 ก็เหมือนกัน คือมี Advisor 2 เป็นที่ปรึกษา แต่ที่ปรึกษาไม่ได้อยู่ในตาราง Advisor)
กรณี Right Join ...
http://www.g2gnet.com/webboard/images/vbnet/DBRight.png
ประกอบด้วยสมาชิก 6 รายการ
SELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student RIGHT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentNamehttp://www.g2gnet.com/webboard/images/vbnet/VBRight.png
หมายความว่า Advisor 5 ยังไม่ได้เป็นที่ปรึกษาให้นักศึกษาคนใดๆเลย
ทั้งสองตาราง หากมาทำ Union หรือ Full Outer Join กัน
http://www.g2gnet.com/webboard/images/vbnet/DBFull.png
ก็จะมีสมาชิกทั้งหมด 8 รายการ อ้าววว ทำไมไม่ใช่ 10 ล่ะ ... ก็เพราะว่ามันมีความสัมพันธ์กันอยู่ 5 รายการ และไม่เกี่ยวข้องกันทางซ้าย 2 รายการ และไม่เกี่ยวข้องกันทางขวา 1 รายการ เลยรวมได้แค่ 8 รายการนั่นเอง
SELECT Student.StudentPK, Student.StudentName, Student.AdvisorFK, Advisor.AdvisorPK
FROM Student LEFT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
UNION http://www.g2gnet.com/webboard/images/vbnet/VBFull.png
กรณีของ MS Access จะไม่มีคำสั่ง SQL ในการ Full Outer Join เราแก้ปัญหานี้ด้วยการใช้ LEFT และ RIGHT มารวมกันแทนครับผม
โค้ด VB.NET เพื่อช่วยในการเรียนรู้และเสริมสร้างความเข้าใจ ...
Imports System.Data.OleDb
Public Class frmJoinDBMethod
Dim Conn As OleDbConnection
' / --------------------------------------------------------------------------------
' / FIRST : Connect MS Access DataBase
Public Function ConnectDataBase() As System.Data.OleDb.OleDbConnection
Dim strPath As String = Application.StartupPath.ToLower
'// MS Access 2007+ DB at data folder.
strPath = strPath.Replace("\bin\debug", "\data").Replace("\bin\release", "\data").Replace("\bin\x86\debug", "\data")
If Microsoft.VisualBasic.Right(strPath, 1) <> "\" Then strPath = strPath + "\"
Try
'//
Dim strConn As String = _
"Provider = Microsoft.ACE.OLEDB.12.0;"
strConn += _
"Data Source = " & strPath & "SampleJoin.accdb"
Conn = New OleDb.OleDbConnection(strConn)
'// Connection (Conn)
Conn.ConnectionString = strConn
'// Return Connection
Return Conn
Catch ex As Exception
MessageBox.Show(ex.Message)
Conn = Nothing
Return Conn
End Try
End Function
Private Sub frmLeftRightInnerJoin_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.CenterToScreen()
' / --------------------------------------------------------------------------------
' Setup DataGridView @Run Time
With dgvData
.RowHeadersVisible = False
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeRows = False
.MultiSelect = False
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.ReadOnly = True
.Font = New Font("Tahoma", 9)
' Header style
With .ColumnHeadersDefaultCellStyle
.BackColor = Color.Navy
.ForeColor = Color.White
.Font = New Font(dgvData.Font, FontStyle.Bold)
End With
'// Auto adjust columns size.
dgvData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
dgvData.AutoResizeColumns()
End With
'//
Conn = ConnectDataBase()
lblRecordCount.Text = ""
End Sub
' / --------------------------------------------------------------------------------
' / Sub Program to show Inner, Left and Right Join
Private Sub RetrieveData(Optional ByVal JoinType As Byte = 0)
Dim strSQL As String
'// 0 = Inner, 1 = Left and 2 = Right Join, 3 = Union
Select Case JoinType
'// INNER JOIN
Case 0
strSQL = _
" SELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName " & _
" FROM Student INNER JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK " & _
" ORDER BY Student.StudentPK "
'// LEFT JOIN
Case 1
strSQL = _
" SELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName " & _
" FROM Student LEFT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK " & _
" ORDER BY Student.StudentPK "
'// RIGHT JOIN
Case 2
strSQL = _
" SELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName " & _
" FROM Student RIGHT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK " & _
" ORDER BY Student.StudentName "
'// UNION
Case 3
strSQL = _
" SELECT Student.StudentPK, Student.StudentName, Student.AdvisorFK, Advisor.AdvisorPK " & _
" FROM Student LEFT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK " & _
" UNION " & _
" SELECT Student.StudentPK, Student.StudentName, Student.AdvisorFK, Advisor.AdvisorPK " & _
" FROM Student RIGHT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK "
'" FROM Advisor LEFT JOIN Student ON Advisor.AdvisorPK = Student.AdvisorFK "
End Select
'// Start
Try
If Conn.State = ConnectionState.Closed Then Conn.Open()
Dim Cmd As New OleDb.OleDbCommand(strSQL, Conn)
Dim Reader As OleDb.OleDbDataReader = Cmd.ExecuteReader
Dim DT As DataTable = New DataTable
DT.Load(Reader)
dgvData.DataSource = DT
DT.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'//
lblRecordCount.Text = ""
End Sub
'// INNER
Private Sub itemInner_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemInner.Click
Call RetrieveData(0)
End Sub
'// LEFT
Private Sub itemLeft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemLeft.Click
Call RetrieveData(1)
End Sub
'// RIGHT
Private Sub itemRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemRight.Click
Call RetrieveData(2)
End Sub
'// UNION
Private Sub itemFull_Click(sender As System.Object, e As System.EventArgs) Handles itemFull.Click
Call RetrieveData(3)
End Sub
Private Sub itemClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles itemClose.Click
Me.Close()
End Sub
Private Sub frmLeftRightInnerJoin_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
If Conn.State = ConnectionState.Open Then Conn.Close()
Me.Dispose()
Application.Exit()
End Sub
End Classดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่
ขอบคุณครับ ขอบพระคุณคัพ อาจารย์ :loveliness::loveliness: ขอบคุณครับ
หน้า:
[1]