Archive for the ‘SQL Server Programming’ Category

 

Ghép Nối Nhiều Bản Ghi Vào Một Dòng

Ví dụ bạn có bảng:
ProductID CustomerName
---------- -------------
1          Tuấn
1          Minh
1          Linh
2          Ngọc
2          Hiền

Bạn muốn kết quả ra như sau:
ProductID CustomerName
---------- -------------
1          Tuấn, Minh, Linh
2          Ngọc, Hiền

Bạn có thể dùng câu lệnh này:

SELECT DISTINCT C2.ProductID, 
    SUBSTRING(
        (
            SELECT ','+C1.CustomerName  AS [TEXT()]
            FROM dbo.Customer C1
            WHERE C1.ProductID = C2.ProductID
            ORDER BY C1.ProductID
            FOR XML PATH ('')
        ), 2, 1000) CustomerList
FROM dbo.Customer C2

Trường hợp bạn không cần group by ProductID mà chỉ cần một danh sách khách hàng nối với nhau, bạn có thể dùng câu lệnh đơn giản hơn sau:

DECLARE @NAMES NVARCHAR(4000) 
SELECT @NAMES = COALESCE(@NAMES + ', ', '') + CustomerName 
FROM dbo.Customer
SELECT @NAMES
Posted on 18/12/2014 by Vũ Huy Tâm | Categories: SQL Server Programming, Tip & Trick

Ứng Dụng của Join Bất Cân Bằng

Tiếp theo bài viết Cẩn thận với Join bất cân bằng, bài viết này mô tả một trường hợp thường gặp có thể xử lý bằng Join bất cân bằng (còn được gọi bằng Non Equi-Joins).
Đó là những bài toán liên quan đến cách tính bậc thang.
Ví dụ giá điện dùng trong khoảng 0-100 thì áp mức giá 100 cho 1 số, từ 101 – 200 lại áp mức giá 200. Cần tính tiền cho từng khách hàng với số điện dùng trong tháng.
Hoặc trong viễn thông, áp giá cho cuộc gọi từ 0-10 giây đầu là 1 đồng, từ giây thứ 11 là 2 đồng… Trong bưu chính, khối lượng hàng hóa từ 0-200g thì mức giá là 1000 đồng, từ 200-400g là 2000 đồng…
Để giải quyết bài toán này có nhiều cách, một trong số những cách thức hiệu quả là sử dụng Join bất cân bằng vì những ưu điểm sau:
- Xử lý hàng loạt, không sử dụng Cursor
- Có thể cài đặt bằng SQL, thuận tiện khi triển khai trên những hệ thống khác ngoài SQL Server như Oracle, MySQL…

MÔ TẢ BẢNG … đọc tiếp »

Posted on 29/9/2014 by Guess Post: Vũ Minh Tâm | Categories: SQL Server Programming

Cẩn Thận Với Join Bất Cân Bằng

Thông thường khi viết lệnh JOIN, trong biểu thức ở mệnh đề join bạn dùng toán tử “=”. Kiểu join này tạm gọi là join cân bằng, còn kiểu join tạm gọi là bất cân bằng là khi biểu thức ở mệnh đề join dùng các toán tử bất cân bằng như >, < , !=... … đọc tiếp »

Posted on 10/9/2014 by Vũ Huy Tâm | Categories: SQL Server Programming

LEFT JOIN Với Mệnh Đề WHERE

Trong bài Một Vài Kiểu Viết Join tôi có đưa ra một số cách viết câu lệnh join tương đương nhau, trong đó điều kiện JOIN có thể chuyển qua lại với mệnh đề WHERE. Tuy điều này đúng với INNER JOIN, khi bạn dùng LEFT JOIN sẽ dẫn đến kết quả sai ngoài mong đợi. Hãy xem xét qua ví dụ: bạn có một database về bán hàng điện thoại, gồm có hai bảng là MatHang bao gồm các loại điện thoại, và BanHang chứa các giao dịch bán hàng. Dữ liệu như sau: … đọc tiếp »

Posted on 26/2/2014 by Vũ Huy Tâm | Categories: SQL Server Programming

Bảng Tạm và Biến Kiểu Bảng

Bảng tạm (temporary table) và biến kiểu bảng (table variable) là 2 phương tiện để lưu dữ liệu tạm thời khi đang xử lý. Bảng tạm có tên bắt đầu bằng dấu “#”, bạn có thể tạo bảng tạm bằng lệnh CREATE TABLE và khai báo các cột của nó; hoặc bạn có thể vừa tạo và thêm dữ liệu vào bằng SELECT INTO. Với biến kiểu bảng thì bạn phải khai báo trước mới có thể dùng được, và khi khai báo bạn phải định nghĩa các cột của nó:

--tạo bảng trực tiếp
CREATE TABLE #t1 (C VARCHAR(50))
 
--vừa tạo bảng và thêm dữ liệu vào
SELECT C
INTO #t2
FROM dbo.SomeTable
 
--khai báo biến kiểu bảng
DECLARE @t TABLE(C VARCHAR(50))
INSERT INTO @t SELECT 1
SELECT * FROM @t

Bảng tạm khai báo ở trên gọi là bảng tạm cục bộ (local temp table), SQL Server còn cung cấp bảng tạm toàn cục (global temp table) với tên bắt đầu bằng hai dấu “##”. Trong bài viết này khi nhắc đến bảng tạm là tôi chỉ nói về bảng tạm cục bộ, vì bạn sẽ chủ yếu dùng đến loại này. … đọc tiếp »

Posted on 9/10/2013 by Vũ Huy Tâm | Categories: SQL Server Programming

Tản mạn về NULL

1. NULL là một giá trị đặc biệt có mặt trong tất cả các loại dữ liệu, từ kiểu số, ngày, chuỗi, đến bit… Nó đại diện cho giá trị “không biết”, hoặc “không tồn tại”. NULL không trùng với số 0 của kiểu số và cũng không trùng với chuỗi trống (”) của kiểu chuỗi. Ví dụ bạn có bảng dữ liệu sinh viên có chứa cột số lần thi lại; nếu một bản ghi chứa NULL ở cột này có nghĩa là ta không biết số lần thi lại của sinh viên đó là bao nhiêu; điều này khác với khi nó chứa 0 nghĩa là ta đã biết sinh viên đó chưa phải thi lại môn nào.
Vì NULL nghĩa là “không biết” nên mọi thao tác với NULL đều dẫn đến NULL. Đây là điều bạn cần ghi nhớ để tránh phiền phức khi liên quan đến xử lý NULL. … đọc tiếp »

Posted on 26/8/2013 by Vũ Huy Tâm | Categories: SQL Server Programming

Parameter Sniffing

Trước khi vào bài viết, tôi muốn kể lại một vài tình huống tôi đã trải qua.
Tình huống 1: Một ngày nọ, một thành viên trong nhóm Database của tôi gặp một hiện tượng kì lạ. Stored Procedure mà cậu ấy viết khi chạy trên môi trường test rất tốt, thời gian xấp xỉ 1 giây. Tuy nhiên khi đưa lên hệ thống thật, thì lại chạy ì ạch mất khoảng 30 giây.
Cậu ấy thay hết giá trị vào stored, chạy trên SSMS dưới dạng câu SQL bình thường thì lại chạy tốt. Vò đầu bứt tai một hồi cậu ấy đâm ra nghi ngờ khi sử dụng Stored Procedure và có kế hoạch thay hết Stored đã viết bằng dynamic sql để tăng hiệu năng. … đọc tiếp »

Posted on 25/6/2013 by Guess Post: Vũ Minh Tâm | Categories: SQL Server Programming, Stored Procedure

Thứ Tự Xử Lý Điều Kiện Ở Mệnh Đề WHERE

Theo bạn các điều kiện trong mệnh đề WHERE được xử lý theo thứ tự nào, từ phải sang trái hay từ trái sang phải? Thực tế là, chúng không phải luôn luôn được xử lý theo một thứ tự nhất định như các ngôn ngữ khác. Chúng được xử lý theo cách SQL Server đánh giá là đạt hiệu quả cao nhất với từng câu lệnh. Nếu bạn viết code các điều kiện của mệnh đề WHERE dựa trên giả định chúng được xử lý theo thứ tự nào đó, bạn sẽ gặp tình huống câu lệnh bị lỗi khi thứ tự xử lý bị đảo ngược (ví dụ khi lượng dữ liệu thay đổi và/hoặc có thêm index mới được tạo…).
Ta hãy thực hiện thí nghiệm sau: … đọc tiếp »

Posted on 31/10/2012 by Vũ Huy Tâm | Categories: SQL Server Programming, Tip & Trick

Các Mức Isolation Level

Isolation level là một thuộc tính của transaction, qui định mức độ cô lập của dữ liệu mà transaction có thể truy nhập vào khi dữ liệu đó đang được cập bởi một transaction khác. Khi một transaction cập nhật dữ liệu đang diễn ra, một phần dữ liệu sẽ bị thay đổi (ví dụ một số bản ghi của bảng được sửa đổi hoặc bị xóa bỏ, một số được thêm mới), vậy các transaction hoặc truy vấn khác xảy ra đồng thời và cùng tác động vào các bản ghi đó sẽ diễn ra thế nào? Chúng sẽ phải đợi đến khi transaction đầu hoàn thành hay có thể thực hiện song song, kết quả dữ liệu nhận được là trong khi hay sau khi cập nhật? Bạn có thể điều khiển những hành vi này thông qua việc đặt isolation level của từng transaction. SQL Server cung cấp các mức isolation level sau xếp theo thứ tự tăng dần của mức độ cô lập của dữ liệu: Read Uncommitted, Read Commited, Repeatable Read, và Serializable. Từ bản 2005 bắt đầu bổ sung thêm một loại mới là Snapshot. Phần còn lại của bài này sẽ đi vào chi tiết của từng loại. … đọc tiếp »

Posted on 23/10/2012 by Vũ Huy Tâm | Categories: SQL Server Programming

Di Chuyển Dữ Liệu Qua Bảng Khác

Khi cần chuyển các bản ghi từ một bảng này sang một bảng khác, bạn có hai cách làm: dùng lệnh INSERT INTO … SELECT FROM…; hoặc dùng SELECT INTO…FROM… Mỗi cách có ưu điểm và nhược điểm riêng, cũng như có phạm vi ứng dụng nhất định. Khi lượng dữ liệu cần di chuyển càng lớn thì sự khác biệt giữa hai cách làm càng rõ. … đọc tiếp »

Posted on 7/3/2012 by Vũ Huy Tâm | Categories: SQL Server Programming