Thứ Bảy, 30 tháng 5, 2015

SQL - Bài 13: Join nâng cao




Trong bài học hôm nay chúng ta sẽ cùng học về:
1. Join nâng cao hay join thông minh trong SQL server
2. Chỉ lấy các hàng không kết hợp của bảng bên trái
3. Chỉ lấy các hàng không kết hợp của bảng bên phải
4. Chỉ lấy các hàng không kết hợp của cả 2 bảng trái và phải
Trước khi học bài này bạn nên xem lại bài 12 - phép kết

Xem xét các bảng Employees (tblEmployee) and Departments (tblDepartment)
Employees


Departments Table (tblDepartment)


Làm thế nào để lấy chỉ các hàng không kết hợp của bảng bên trái. Kết quả được tạo ra như bên dưới


Truy vấn:
SELECT       Name, Gender, Salary, DepartmentName
FROM           tblEmployee E
LEFT JOIN   tblDepartment D
ON                 E.DepartmentId = D.Id
WHERE        D.Id IS NULL



Làm thế nào để chỉ lấy các hàng không kết hợp của bảng bên phải



Truy vấn:
SELECT         Name, Gender, Salary, DepartmentName
FROM             tblEmployee E
RIGHT JOIN    tblDepartment D
ON                   E.DepartmentId = D.Id
WHERE          E.DepartmentId IS NULL 



Làm thể nào để lấy các hàng không kết hợp từ cả 2 bảng bên trái và bảng bên phải. Các hàng kết hợp phải bị loại bỏ


Truy vấn:
SELECT         Name, Gender, Salary, DepartmentName
FROM              tblEmployee E
FULL JOIN      tblDepartment D
ON                   E.DepartmentId = D.Id
WHERE          E.DepartmentId IS NULL
OR                   D.Id IS NULL



Thứ Sáu, 29 tháng 5, 2015

SQL - Bài 12: Kết trong SQL

Phép join trong SQL server là sử dụng câu lệnh truy vấn để lấy dữ liệu từ 2 hoặc nhiều bảng có quan hệ. Trong bảng được tạo ra sẽ có ràng buộc khóa ngoại kết nối đến mỗi bảng.

Nên xem lại phần 3 và phần 5 trong series, trước khi tiếp tục với video này

Trong SQL server, có những loại join sau đây:
1. CROSS JOIN
2. INNER JOIN
3. OUTER JOIN

Outer join cũng chia làm 3 loại sau:
1. Left Join hoặc Left Outer Join
2. Right Join hoặc Right Outer Join
3. Full Join hoặc Full Outer Join


Bây giờ chúng ta sẽ hiểu về tất cả các loại JOIN với các ví dụ và sự khác nhau giữa chúng.
Bảng Employee
Bảng Department 
Đoạn script để tạo ra 2 bảng này:
Create table tblDepartment
(
     ID int primary key,
     DepartmentName nvarchar(50),
     Location nvarchar(50),
     DepartmentHead nvarchar(50)
)
Go

Insert into tblDepartment values (1, 'IT', 'London', 'Rick')
Insert into tblDepartment values (2, 'Payroll', 'Delhi', 'Ron')
Insert into tblDepartment values (3, 'HR', 'New York', 'Christie')
Insert into tblDepartment values (4, 'Other Department', 'Sydney', 'Cindrella')
Go

Create table tblEmployee
(
     ID int primary key,
     Name nvarchar(50),
     Gender nvarchar(50),
     Salary int,
     DepartmentId int foreign key references tblDepartment(Id)
)
Go

Insert into tblEmployee values (1, 'Tom', 'Male', 4000, 1)
Insert into tblEmployee values (2, 'Pam', 'Female', 3000, 3)
Insert into tblEmployee values (3, 'John', 'Male', 3500, 1)
Insert into tblEmployee values (4, 'Sam', 'Male', 4500, 2)
Insert into tblEmployee values (5, 'Todd', 'Male', 2800, 2)
Insert into tblEmployee values (6, 'Ben', 'Male', 7000, 1)
Insert into tblEmployee values (7, 'Sara', 'Female', 4800, 3)
Insert into tblEmployee values (8, 'Valarie', 'Female', 5500, 1)
Insert into tblEmployee values (9, 'James', 'Male', 6500, NULL)
Insert into tblEmployee values (10, 'Russell', 'Male', 8800, NULL)
Go

Cấu trúc Join cơ bản như sau:
SELECT      ColumnList
FROM           LeftTableName
JOIN_TYPE  RightTableName
ON                 JoinCondition

CROSS JOIN, các bảng được tạo ra là tích đề các của 2 bảng được join. Ví dụ, trong bảng Employees chúng ta có 10 hảng và trong bảng Departments chúng ta có 4 hàng. Vậy nên, cross join giữa 2 bảng sẽ tạo ra 40 hàng. Cross Join không phải sử dụng mệnh đề ON

Câu lệnh truy vấn CROSS JOIN:
SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
CROSS JOIN tblDepartment

JOIN hay INNER JOIN
Viết một truy vấn, lấy dữ liệu Name, Gender, Salary và DepartmentName từ bảng Empoyess và bảng Department. Bảng đưa ra của truy vấn trên phải như bên dưới. 


SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
INNER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

hoặc 

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Chú ý: JOIN và INNER JOIN có ý nghĩa như nhau, không có cái nào tốt hơn cái nào. Nhưng sẽ là tốt hơn nếu chúng ta sử dụng INNER JOIN, nó làm sáng tỏ mục đích của bạn.
Nếu bạn nhìn vào output, chúng ta chỉ có 8 hàng, nhưng trong bảng Empoyees, chúng ta có 10 hàng. Chúng ta không lấy 2 bản ghi JAMES và RUSSELL. Nó có nghĩa là DEPARTMENTID trong bảng Employees là NULL cho 2 giá trị employees và không khớp với cột ID trong bảng Departments

Vì vậy trong bảng tóm tắt, nó chỉ trả về các hàng kết hợp giữa 2 bảng. Không được loại bỏ chúng.

LEFT JOIN hoặc LEFT OUTER JOIN
Bây giờ nói tiếp, tôi muốn tất cả các dòng trong bảng Employees, thêm 2 bản ghi là JAMES và RUSSELL. Tôi muốn output như bên dưới
 
SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
LEFT OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Hoặc

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
LEFT JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Chú ý: Khi bạn sử dụng Left Join hoặc Left Outer Join. Từ khóa Outer là không bắt buộc.
LEFT JOIN, trả tất cả những hàng kết hợp hoặc không kết hợp từ bảng bên trái. Trong thực tế INNER JOIN và LEFT JOIN được sử dụng rỗng rãi.

RIGHT JOIN hoặc RIGHT OUTER JOIN
Tôi muốn tất cả các hàng ở cột bên phải. Câu truy vấn để tạo ra các bảng như bên dưới:


SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
RIGHT OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Hoặc

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
RIGHT JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Chú ý: Khi bạn sử dụng Right Join hoặc Right Outer Join. Từ khóa Outer là không bắt buộc.
RIGHT JOIN, trả tất cả những hàng kết hợp hoặc không kết hợp từ bảng bên phải.

FULL JOIN or FULL OUTER JOIN
I want all the rows from both the tables involved in the join. The query output should be, as shown below. 

FULL JOIN hoặc FULL OUTER JOIN
Tôi muốn tất cả các hàng từ 2 bảng liên quan đều tham gia. Kết quả truy vấn sẽ có như hình dưới đây

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
FULL OUTER JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

OR

SELECT Name, Gender, Salary, DepartmentName
FROM tblEmployee
FULL JOIN tblDepartment
ON tblEmployee.DepartmentId = tblDepartment.Id

Lưu ý: Chúng ta có thể sử dụng FULL OUTER JOIN hoặc FULL JOIN. Từ khóa OUTER là không bắt buộc.
FULL JOIN, trả về tất các hàng kết hợp từ bên trái và bên phải. Thêm vào cả những hàng không kết hợp.

Tóm gọn:

Thứ Tư, 27 tháng 5, 2015

SQL - Bài 11: GROUP BY

Trong SQL Server chúng ta có rất nhiều chức năng tổng hợp. Ví dụ như
1. Count()
2. Sum()
3. avg()
4. Min()
5. Max()

Mệnh đề GROUP by được sử dụng để 
lựa chọn một số hàng trong một tập hợp  mà giá trị của nó thuộc về một hoặc nhiều cột hoặc thỏa mãn một  biểu thức nào đó. Nó luôn được sử dụng với một hoặc nhiều hơn các hàm tổng hợp trên kia.


Tôi muốn tạo một truy vấn, mà nó sẽ ra tổng hợp lương của mỗi thành phố. Bảng xuất ra giống như ở dưới

Câu lệnh truy vấn để lấy thông lương của các thành phố:
Chúng ta sử dung hàm tổng hợp SUM() cho cột Salary, và gom lại bằng cột thành phố. Nó hiệu quả thêm ở chổ cho biết tổng lương của người lao động trong cùng một thành phố. 
Select City, SUM(Salary) as TotalSalary 
from tblEmployee
Group by City

Lưu ý: Nếu bạn bỏ qua không nhóm bằng mệnh đề group by và cố gắng thực thi truy vấn nó sẽ hiện thông báo lỗi như sau -Column 'tblEmployee.City' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 

Bây giờ, tôi muốn một truy vấn, nó tính tổng lương bằng City và gender. Kết quả thực thi như sau

Truy vấn lấy tổng các lương bởi city và gender. Nó có thể gom nhóm bằng nhiều cột. Trong truy vấn này, chúng ta gom nhóm thuộc tính đầu tiền là city và sau đó là gender
Select City, Gender, SUM(Salary) as TotalSalary
from tblEmployee
group by City, Gender

Bây giờ, tôi muốn một truy vấn trả về tổng các lương và tổng số các nhân viên theo thành phố và theo giới tính. Kết quả xuất ra như sau:


Truy vấn này sẽ trả về tổng lương và tổng số nhân viên theo City và gender. Sự khác biệt duy nhất ở đây là chúng ta sử dụng hàm tổng hợp Coutn()Select City, Gender, SUM(Salary) as TotalSalary,
COUNT(ID) as TotalEmployees

from tblEmployee
group by City, Gender

Lọc các giá trị:
Mệnh đề WHERE được sử dụng để lọc các hàng trước khi tổng hợp, trong khi mệnh đề HAVING là sử dụng để lọc nhưng lọc nhưng là lọc các điều kiện trên nhóm

SELECT <danh sách các cột>
FROM <danh sách các bảng>
WHERE <điều kiện>
GROUP BY <danh sách các cột gom nhóm>
HAVING <điều kiện trên nhóm>

Lọc các hàng sử dụng mệnh đề WHERE, trước khi tổng hợp theo nhóm:Select City, SUM(Salary) as TotalSalary
from tblEmployee
Where City = 'London'
group by City

Lọc các nhóm sử dụng mệnh đề HAVING, sau khi tất cả đã được tổng hợp:Select City, SUM(Salary) as TotalSalary
from tblEmployee
group by City
Having City = 'London'

"From a performance standpoint, you cannot say that one method is less efficient than the other. Sql server optimizer analyzes each statement and selects an efficient way of executing it. As a best practice, use the syntax that clearly describes the desired result. Try to eliminate rows that 
you wouldn't need, as early as possible"


Cũng có thể kết hợp WHERE và HAVINGSelect City, SUM(Salary) as TotalSalary
from tblEmployee
Where Gender = 'Male'
group by City
Having City = 'London'

Sự khác biệt giữa 2 mệnh đề WHERE và HAVING:
1. WHERE clause can be used with - Select, Insert, and Update statements, where as HAVING clause can only be used with the Select statement.
2. WHERE filters rows before aggregation (GROUPING), where as, HAVING filters groups, after the aggregations are performed.
3. Aggregate functions cannot be used in the WHERE clause, unless it is in a sub query contained in a HAVING clause, whereas, aggregate functions can be used in Having clause.












SQL - Bài 10: Câu lệnh Select

Cú pháp câu lệnh select cơ bản
SELECT Column_List
FROM Table_Name

Nếu bạn muốn chọn tất cả các cột, bạn có thể sử dụng *. Về mặt hiệu suất thì tốt hơn so với dùng danh sách các cột.
SELECT *
FROM Table_Name 

Chọn các hàng loại bỏ giá trị trùng sử dụng từ khóa DISTINCT
SELECT DISTINCT Column_List
FROM Table_Name

ví dụSelect distinct city from tblPerson

Lọc các hàng với mệnh đề WHERESELECT Column_List
FROM Table_Name
WHERE Filter_Condition

ví dụ: Select Name, Email from tblPerson where City = 'London'


Chú ý: các giá trị chuỗi phải có mặt trong dấu ngoặc đơn, nhưng không bắt buộc với các giá trị số học.

Các toán tử khác nhau có thể được sử dụng trong cùng một mệnh đề WHERE

SQL - Bài 9: Unique key constraint - Tạo ràng buộc duy nhất

Chúng ta sử dụng ràng buộc duy nhất để thực thi tính năng giá trị độc nhất của cột, tức là không cho phép giá trị nhân bản nào trong một cột, kể cả NULL cũng chỉ có duy nhất một giá trị không được phép có 2 giá trị NULL trên một cột (điều này khác với lý thuyết CSDL :D). Chúng ta có thể thêm thuộc tính khóa ràng buộc này bằng 2 cách:

Cách thứ nhất sử dụng giao diện của SSMS:
1. Chuột phải vào bảng và chọn Design
2. Chuột phải vào cột và chon Indexes/Keys...
3. Click vào Add
4. Trong Columns, chọn tên cột mà bạn muốn unique
5. Trong Type chọn Unique Key
6. Click Close, lưu bảng lại.

Để tạo ra ràng buộc sử dụng câu lệnh truy vấn ta thực hiện như sau
Alter Table Table_Name
Add Constraint Constraint_Name Unique(Column_Name)

Cả hai khóa chính và khóa unique đều được sử dụng để thực thi tính năng duy nhất. Vậy nên chúng ta chọn cái nào hơn cái nào? Một bảng chỉ có thể có duy nhất một khóa chính. Nếu bạn thực thi thuộc tính duy nhất trên 2 hoặc nhiều cột thì chỉ còn cách sử dụng unique constraint :)))).

Sự khác nhau giữa Primary key constraint và Unique key constraint là gì? Câu hỏi này được sử dụng rất thường xuyên trong các cuộc phỏng vấn.
1. Một bảng chỉ có duy nhất một khóa chính, nhưng có thể có nhiều hơn unique key
2. Primary key không cho phép các giá trị null, trong khi đso unique cho phép 1 giá trị null.

Để xóa một ràng buộc unique
1. Click chuột phải vào constraint and delete
hoặc
2. Sử dụng câu lênh truy vấn
Alter Table tblPerson
Drop COnstraint UQ_tblPerson_Email