Tôi có hai bảng. Một đại diện cho các hóa đơn vẫn mở (bảng #OPEN
) và một số khác thể hiện số tiền có sẵn (bảng #overpay
). Cả hai đều có một cột USERID
mà họ có thể được tham gia:Cách tham gia hai bảng nhưng chỉ sử dụng mỗi hàng một lần
CREATE TABLE #OVERPAY(OID INT, USERID CHAR(1), Rest INT)
CREATE TABLE #OPEN(IID INT, USERID CHAR(1), Amt INT, OpenROW INT)
CáC#OPEN bảng có một cột OpenRow
mà số tiền mở được sắp xếp (mỗi người dùng). Tôi muốn để lập bản đồ mục từ bảng #OVERPAY
tới mục trong bảng #OPEN
theo cách sau:
- Một mục được ánh xạ khi # OVERPAY.Rest> = # OPEN.AMT
- nhỏ hơn giá trị trong #OPEN. OpenRow được ánh xạ đầu tiên
- Mỗi mục trong #OVERPAY chỉ có thể được sử dụng một lần
- Mỗi mục trong #OPEN chỉ có thể được sử dụng một lần
hai điểm cuối cùng trong danh sách đó là những gì mang lại cho tôi một đau đầu.
Đây là một số dữ liệu chế giễu:
OID USERID REST
--------------------
1 'A' 10
2 'A' 15
3 'F' 5
4 'H' 20
5 'H' 5
INSERT INTO #OVERPAY(OID, USERID, Rest)
VALUES (1, 'A', 10), (2, 'A', 15), (3, 'F', 5),
(4, 'H', 20), (5, 'H', 5)
OID USERID Amt OpenRow
-----------------------------
1 'A' 10 1
2 'A' 10 2
3 'A' 15 3
4 'F' 5 1
5 'H' 15 1
6 'H' 10 2
7 'P' 33 1
INSERT INTO #OPEN(IID, USERID, Amt, OpenROW)
VALUES (1, 'A', 10, 1), (2, 'A', 10, 2),
(3, 'A', 15, 3), (4, 'F', 5, 1),
(5, 'H', 15, 1), (6, 'H', 10, 2),
(7, 'P', 33, 1)
Kết quả mong muốn sẽ là:
OID IID
----------
1 1
2 2
3 4
4 5
tôi biết làm thế nào tôi có thể làm điều đó với một CURSOR
:
CREATE TABLE #map (OID INT, IID INT)
CREATE TABLE #usedIID(IID INT)
DECLARE @OID INT, @USERID CHAR(1), @Rest INT
DECLARE ov_cursor CURSOR FOR
SELECT OID, USERID, REST
FROM #OVERPAY
OPEN ov_cursor
FETCH NEXT FROM ov_cursor INTO @OID, @USERID, @REST
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @IID INT
INSERT INTO #map (OID, IID)
OUTPUT inserted.IID INTO #usedIID (IID)
SELECT TOP 1 @OID, o.IID
FROM #OPEN o
LEFT JOIN #usedIID u ON u.IID = o.IID
WHERE o.USERID = @USERID AND o.Amt <= @REST AND u.IID IS NULL
FETCH NEXT FROM ov_cursor INTO @OID, @USERID, @REST
END
CLOSE ov_cursor
DEALLOCATE ov_cursor
Nhưng kể từ điều này thật khủng khiếp về hiệu suất (tôi đang làm việc với một bộ dữ liệu khổng lồ) Tôi đang tìm kiếm một tùy chọn để làm điều đó mà không cần bất kỳ vòng lặp
YES! Điều đó dường như chính xác, những gì tôi đang tìm kiếm. Tôi sẽ thử nó trong kịch bản thế giới thực của tôi và quay lại sau đó. Cảm ơn bạn! –
Nó hoạt động như một sự quyến rũ. Giải pháp rất đẹp! –
Và câu hỏi hay. – Serg