|  | 
 
|  ในบทความนี้ แอดมินจะจำลอง เพื่อแสดงให้เห็นถึงการจอย (JOIN) หรือเชื่อมความสัมพันธ์ระหว่างตารางข้อมูล 2 ตารางเข้าหากัน ด้วยวิธีการกระจายข้อมูลออกให้เห็นในรูปแบบของเซ็ต (SET) โดยใช้ไฟล์ฐานข้อมูล Microsoft Access มาเป็นตัวอย่าง ซึ่งมันก็ใช้ไวยากรณ์ที่คล้ายๆกันฐานข้อมูลตัวอื่นๆนั่นแหละครับท่านผู้ชม ...
 
  สมมุติชื่อเล่นตาราง 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) ...
 
  พบว่าตาราง A และ B หากมีความสัมพันธ์กันแบบไร้เงื่อนไขก็จะมีสมาชิกอยู่ 5 รายการ ซึ่งกรณีของ Inner Join นี้เราต้องใช้งานบ่อยมาก
 ตาราง A JOIN กับตาราง B เมื่อคีย์รอง AdvisorFK มีค่าเท่ากับคีย์หลัก AdvisorPKคัดลอกไปที่คลิปบอร์ดSELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student INNER JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentPK
  ความหมายคือ รายชื่อของนักศึกษาที่มีอาจารย์เป็นที่ปรึกษาเรียบร้อย
 
 กรณี Left Join ...
 
  ประกอบไปด้วยสมาชิก 7 รายการ
 
 คัดลอกไปที่คลิปบอร์ดSELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student LEFT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentPK
 Student 2 ต้องให้ Advisor 8 เป็นที่ปรึกษา แต่ทว่า Advisor 8 ไม่มีรายชื่อปรากฏอยู่ในตาราง Advisor (กรณี Student 4 ก็เหมือนกัน คือมี Advisor 2 เป็นที่ปรึกษา แต่ที่ปรึกษาไม่ได้อยู่ในตาราง Advisor)
 
 กรณี Right Join ...
 
  ประกอบด้วยสมาชิก 6 รายการ
 
 คัดลอกไปที่คลิปบอร์ดSELECT Student.StudentPK, Student.StudentName, Advisor.AdvisorName
FROM Student RIGHT JOIN Advisor ON Student.AdvisorFK = Advisor.AdvisorPK
ORDER BY Student.StudentName
 หมายความว่า Advisor 5 ยังไม่ได้เป็นที่ปรึกษาให้นักศึกษาคนใดๆเลย
 
 ทั้งสองตาราง หากมาทำ Union หรือ Full Outer Join กัน
 
  ก็จะมีสมาชิกทั้งหมด 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 
 กรณีของ MS Access จะไม่มีคำสั่ง SQL ในการ Full Outer Join เราแก้ปัญหานี้ด้วยการใช้ LEFT และ RIGHT มารวมกันแทนครับผม
 
 โค้ด VB.NET เพื่อช่วยในการเรียนรู้และเสริมสร้างความเข้าใจ ...
 
 ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่คัดลอกไปที่คลิปบอร์ด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 = "[Total : " & dgvData.RowCount & " Records.]"
    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
 
 | 
 
xขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึงคุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน  |