从SQL Server中两个表之间的联接结果集中查找第一个匹配项

从SQL Server中两个表之间的联接结果集中查找第一个匹配项,sql,sql-server,join,Sql,Sql Server,Join,我有一个表testrades如下: CREATE TABLE #testtrades ( TradeID int, producttype varchar(10), tradeddate date, settledate date, busunit varchar(5), qty int, price float, amount float, tradeside varchar(1), buysell varchar

我有一个表testrades如下:

CREATE TABLE #testtrades
(
    TradeID int,
    producttype varchar(10),
    tradeddate date,
    settledate date,
    busunit varchar(5),
    qty int,
    price float,
    amount float,
    tradeside varchar(1),
    buysell varchar(1)
)

INSERT #testtrades
SELECT 1,'equity',getdate(),getdate()+3,'bus1',10,100,1000,'S','B'
INSERT #testtrades
SELECT 2,'equity',getdate(),getdate()+3,'bus1',10,100,950,'C','S'
INSERT #testtrades
SELECT 3,'equity',getdate(),getdate()+3,'bus2',11,100,1000,'S','B'
INSERT #testtrades
SELECT 4,'equity',getdate(),getdate()+3,'bus3',10,100,1200,'S','S'
INSERT #testtrades
SELECT 5,'equity',getdate(),getdate()+3,'bus1',10,100,1200,'C','B'
INSERT #testtrades
SELECT 6,'equity',getdate(),getdate()+3,'bus2',10,100,1000,'C','S'
INSERT #testtrades
SELECT 7,'equity',getdate(),getdate()+3,'bus4',10,100,1000,'C','B'
INSERT #testtrades
SELECT 8,'equity',getdate(),getdate()+3,'bus5',10,100,950,'S','S'
INSERT #testtrades
SELECT 9,'equity',getdate(),getdate()+3,'bus5',10,100,1200,'C','S'
INSERT #testtrades
SELECT 10,'equity',getdate(),getdate()+3,'bus4',14,100,1000,'S','B'
INSERT #testtrades
SELECT 11,'equity',getdate(),getdate()+3,'bus6',10,100,1000,'C','S'
INSERT #testtrades
SELECT 12,'equity',getdate(),getdate()+3,'bus7',10,100,950,'C','B'
INSERT #testtrades
SELECT 13,'equity',getdate(),getdate()+3,'bus7',10,100,1200,'C','S'
INSERT #testtrades
SELECT 14,'equity',getdate(),getdate()+3,'bus7',10,100,1000,'S','S'

INSERT #sideA
SELECT * FROM #testtrades
WHERE tradeside='C'

INSERT #sideB
SELECT * FROM #testtrades
WHERE  tradeside='S'

SELECT 
    ROW_NUMBER() OVER (ORDER BY A.tradeID), 
    A.TradeID, B.TradeID 
FROM 
    #sideA A 
JOIN 
    #sideB B ON A.buysell = B.buysell
             AND A.price = B.price
             AND A.Qty = B.Qty
             AND ABS(A.Amount - B.Amount) <= 50
从上面的结果集中,我只想检索第一个匹配的行,就像tradeIDA 2与8和14匹配一样。我只想找回2,8。然后6首先与8匹配。但由于8已与2匹配,因此6不符合条件。然后6与14匹配,所以我想检索该记录。预期结果集如下所示

id tradeIDA tradeIDB
--------------------
1     2       8
4     6      14
5     7       1
6     9       4

也许这能给你一个主意

    ;
        WITH    CTE
                  AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY A.tradeID ) rownum ,
                                A.TradeID TradeA ,
                                B.TradeID TradeB
                       FROM     #sideA A
                                JOIN #sideB B ON A.buysell = B.buysell
                                                 AND A.price = B.price
                                                 AND A.Qty = B.Qty
                                                 AND ABS(A.Amount - B.Amount) <= 50
                     ),
                CTE1
                  AS ( SELECT   rownum ,
                                TradeA ,
                                ROW_NUMBER() OVER ( ORDER BY rownum ) ctr
                       FROM     ( SELECT    rownum ,
                                            TradeA ,
                                            ROW_NUMBER() OVER ( PARTITION BY TradeA ORDER BY rownum ) ctr
                                  FROM      cte
                                ) T
                       WHERE    t.ctr = 1
                     ),
                CTE2
                  AS ( SELECT   TradeB ,
                                ROW_NUMBER() OVER ( ORDER BY rownum ) ctr
                       FROM     ( SELECT    rownum ,
                                            TradeB ,
                                            ROW_NUMBER() OVER ( PARTITION BY TradeB ORDER BY rownum ) ctr
                                  FROM      cte
                                ) T
                       WHERE    t.ctr = 1
                     ),
                CTE3
                  AS ( SELECT   CTE1.TradeA  [tradeIDA],
                                CTE2.TradeB  [tradeIDB]
                       FROM     CTE1
                                JOIN CTE2 ON CTE2.ctr = CTE1.ctr
                     )
            SELECT  *
            FROM    CTE3

无效的对象名称“sideA”。由于您仅根据.TradeID给出行号,因此结果可能是第2 | 8行和第2 | 14行都得到1。请更正此项,以便我们了解您真正想要的订单。我假设按A.TradeID,B.TradeID排序,而不是按A.TradeID排序?这是一个迭代过程。保留第1行,因为它的ID以前不出现。但您保留第4行,尽管第3行中出现了ID 6。这是因为你解雇了第三排。我建议您使用编程语言在SQL之外执行此操作,您可以简单地在数据中循环。@Nemanja Perovic:更改为从testtrades中选择*进入sideA,其中tradeside='C'@von谢谢,我的观点是OP提供的用于重新创建问题的代码在这项工作中有错误。当记录超过500万条时,这是一个好的选择吗
    ;
        WITH    CTE
                  AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY A.tradeID ) rownum ,
                                A.TradeID TradeA ,
                                B.TradeID TradeB
                       FROM     #sideA A
                                JOIN #sideB B ON A.buysell = B.buysell
                                                 AND A.price = B.price
                                                 AND A.Qty = B.Qty
                                                 AND ABS(A.Amount - B.Amount) <= 50
                     ),
                CTE1
                  AS ( SELECT   rownum ,
                                TradeA ,
                                ROW_NUMBER() OVER ( ORDER BY rownum ) ctr
                       FROM     ( SELECT    rownum ,
                                            TradeA ,
                                            ROW_NUMBER() OVER ( PARTITION BY TradeA ORDER BY rownum ) ctr
                                  FROM      cte
                                ) T
                       WHERE    t.ctr = 1
                     ),
                CTE2
                  AS ( SELECT   TradeB ,
                                ROW_NUMBER() OVER ( ORDER BY rownum ) ctr
                       FROM     ( SELECT    rownum ,
                                            TradeB ,
                                            ROW_NUMBER() OVER ( PARTITION BY TradeB ORDER BY rownum ) ctr
                                  FROM      cte
                                ) T
                       WHERE    t.ctr = 1
                     ),
                CTE3
                  AS ( SELECT   CTE1.TradeA  [tradeIDA],
                                CTE2.TradeB  [tradeIDB]
                       FROM     CTE1
                                JOIN CTE2 ON CTE2.ctr = CTE1.ctr
                     )
            SELECT  *
            FROM    CTE3
tradeIDA    tradeIDB
----------- -----------
2           8
6           14
7           1
9           4

(4 row(s) affected)