Cũ 07-30-2010, 02:44 PM   #1
TrungBravo
Bang chủ
 
Tham gia ngày: Sep 2009
Bài gửi: 29
Mặc định Chỉ 1 lệnh thôi

Yêu cầu: từ dữ liệu thu chi (#TransTemp) và số dư đầu (#BalanceTemp) lập sổ quỹ tiền mặt
#BalanceTemp chỉ bằng 1 câu lệnh tạo ra kết quả có nội dung như sau

+--+---------+----+--------+--------+-------+
|Id| Ngay_Ct | Tk |Tien_Thu|Tien_Chi| So_Du |
+--+---------+----+--------+--------+-------+
| 1| 1/1/2010| 111|__500000|_______0|3500000|
| 2| 1/1/2010| 111|_______0|__400000|3100000|
...
+--+---------+----+--------+--------+-------+

trong đó cột So_Du là số dư của tài khoản sau khi nghiệp vụ phát sinh
Câu lệnh tạo bảng temp như sau

Quote:
SET NOCOUNT ON;
IF OBJECT_ID('TempDb..#BalanceTemp') IS NOT NULL DROP TABLE #BalanceTemp;
CREATE TABLE #BalanceTemp (Tk Int, Du_Dau_Ky Numeric(18));

INSERT INTO #BalanceTemp (Tk, Du_Dau_Ky) VALUES (111, 3000000);
INSERT INTO #BalanceTemp (Tk, Du_Dau_Ky) VALUES (112, 4000000);

IF OBJECT_ID('TempDb..#TransTemp') IS NOT NULL DROP TABLE #TransTemp

CREATE TABLE #TransTemp (Id Int Identity (1, 1),
Tk Int,
Ngay_Ct datetime,
Tien_Thu Numeric(18),
Tien_Chi Numeric(18))

DECLARE @_i Numeric(8), @_Thu_Chi Int, @_Tien_Thu Numeric(18),
@_Tien_Chi Numeric(18), @_RandomValue Numeric(18), @_Date datetime;
SELECT @_i = 1, @_Thu_Chi = 1, @_Date = 'Jan 1, 2010';

WHILE @_i <= 10000
BEGIN
SET @_RandomValue = (RAND() * 1000 + RAND() * 1000 + RAND() * 1000) + (RAND() * 100 + RAND() * 100 + RAND() * 100);
IF @_Thu_Chi = 1
SELECT @_Tien_Thu = @_RandomValue , @_Tien_Chi = 0, @_Thu_Chi = 0;
ELSE
SELECT @_Tien_Thu = 0, @_Tien_Chi = @_RandomValue, @_Thu_Chi = 1;

INSERT INTO #TransTemp (Ngay_Ct, Tk, Tien_Thu, Tien_Chi)
VALUES (DATEADD(day, RAND(), @_Date), 111, @_Tien_Thu, @_Tien_Chi);

IF @_Thu_Chi = 1
SET @_Date = DATEADD(day, 1, @_Date)

SET @_i = @_i + 1;
END

CREATE UNIQUE INDEX #PK_TranTemp_Id ON #TransTemp (Id)
__________________
Thiện căn ở tại ḷng ta.
Chữ Tâm kia mới bằng ba chữ Tài

Lần sửa cuối bởi TrungBravo; 07-30-2010 lúc 02:47 PM Lư do: sai lỗi chính tả
TrungBravo đang ẩn   Trả lời với trích dẫn
Cũ 08-05-2010, 09:17 AM   #2
chautinhtri
Đường chủ Hà Nội
 
Tham gia ngày: Aug 2009
Bài gửi: 17
Mặc định Bài bác Trung hiểm quá

SELECT t.id, t.Ngay_Ct, t.Tien_Thu, t.Tien_Chi, rt.Tien_Thu - rt.Tien_Chi AS Du_Cuoi
FROM #TransTemp t
cross apply (SELECT SUM(Tien_Thu) AS Tien_Thu, SUM(Tien_Chi) AS Tien_Chi FROM #TransTemp WHERE id <= t.id) AS rt
ORDER BY t.id

Trả biết chạy thế nào mong anh em đóng góp thêm
chautinhtri đang ẩn   Trả lời với trích dẫn
Cũ 08-05-2010, 11:02 AM   #3
TrungBravo
Bang chủ
 
Tham gia ngày: Sep 2009
Bài gửi: 29
Mặc định

Cán ơn bác chautinhtri đă có phương án cho em. Đây là phương án chạy nhanh và sáng sủa hơn cái em đang có (nhưng chỉ nhanh hơn có 2 giây)
Nhưng thiếu chưa xử lư cái #BalanceTemp, dẫu sao cũng tuyệt vời
Phát huy tinh thần của bác chautinhtri, em vẫn mong nhận được các phương án nữa
__________________
Thiện căn ở tại ḷng ta.
Chữ Tâm kia mới bằng ba chữ Tài
TrungBravo đang ẩn   Trả lời với trích dẫn
Cũ 08-05-2010, 01:34 PM   #4
chautinhtri
Đường chủ Hà Nội
 
Tham gia ngày: Aug 2009
Bài gửi: 17
Mặc định Cái này nữa nhưng...

Nếu số ḍng của bác <= 32767 ḍng th́ có lệnh c̣n nhanh hơn
Nhưng chắc khó có trường hợp đấy
chautinhtri đang ẩn   Trả lời với trích dẫn
Cũ 08-05-2010, 04:58 PM   #5
TrungBravo
Bang chủ
 
Tham gia ngày: Sep 2009
Bài gửi: 29
Mặc định

Phương án ban đầu chạy mất 15 giây

WITH RunningBalance (Id, So_Du)
AS
(
SELECT A.Id, (B.Tien_Thu - B.Tien_Chi) AS So_Du
FROM #TransTemp A CROSS JOIN
#TransTemp B
WHERE B.ID <= A.ID
)
SELECT #TransTemp.Id, Ngay_Ct, Tien_Thu, Tien_Chi, So_Du + #BalanceTemp.Du_Dau_Ky AS [So Du]
FROM #TransTemp LEFT OUTER JOIN
(SELECT Id, SUM(So_Du) So_Du
FROM RunningBalance T GROUP BY Id) Bal
ON #TransTemp.Id = Bal.Id
LEFT OUTER JOIN #BalanceTemp ON #TransTemp.Tk = #BalanceTemp.Tk
ORDER BY #TransTemp.Id

Phương án hiện tại chạy mất 9 giây

SELECT A.Id, Ngay_Ct, A.Tien_Thu, A.Tien_Chi,
(SELECT SUM(Tien_Thu - Tien_Chi) FROM #TransTemp WHERE Id <= A.Id) + C.Du_Dau_Ky AS [So Du]
FROM #TransTemp A
LEFT OUTER JOIN #BalanceTemp C ON A.Tk = C.Tk
ORDER BY A.Id

Cần phương án chạy tối đa là 2 hoặc 3 giây
__________________
Thiện căn ở tại ḷng ta.
Chữ Tâm kia mới bằng ba chữ Tài

Lần sửa cuối bởi TrungBravo; 08-05-2010 lúc 05:10 PM
TrungBravo đang ẩn   Trả lời với trích dẫn
Viết bài mới  Trả lời

Công cụ bài viết T́m trong chủ đề này
T́m trong chủ đề này:

T́m chi tiết
Kiểu hiển thị

Quyền viết bài
Bạn không thể gửi chủ đề mới
Bạn không thể gửi trả lời
Bạn không thể gửi file đính kèm
Bạn không thể sửa bài viết của ḿnh

BB code đang Mở
Mặt cười đang Mở
[IMG] đang Mở
HTML đang Mở

Chuyển đến


Múi giờ GMT +7. Hiện tại là 03:21 PM


Sử dụng mă nguồn vBulletin® Phiên bản 3.8.2
© 2007 - 2010 Nhóm phát triển website và thành viên DTNTHB.COM.
BQT không chịu bất cứ trách nhiệm nào từ bài viết của thành viên.