2014-09-25 98 views
0

我想为一个研究构建一个数据集,并将其分成两组,我们称它们为Hatfields和McCoys。有更多的Hatfields比McCoys,我想匹配每个哈特菲尔德与我定义的足够类似于McCoys的人​​。我希望所有的比赛都是1-1。每个Hatfield应该匹配1个McCoy,并且不应该有超过一次的匹配。有可能会有一些多重比赛,但我想消除这些。我对“最好”的比赛并不挑剔,只是这是一场比赛。使用SQL根据多个条件在2个相互不同的表中匹配记录

会员日期分数
甲2014年2月1日1.00
乙2014年4月4日1.50
Ç2014年9月15日1.00

会员START_DATE END_DATE分数
D 1/1/2014 12/31/2014 1.00
E 6/1/2014 12/31/2014 0.50
˚F2014年1月1日2014年5月31日1.50
ģ2014年1月1日2014年12月31日1.00
ħ2014年8月1日2014年12月31日1.00

上面的表格显示了一个示例(抱歉格式不佳)。我想将ABC的每一个匹配到DEFGH之一,我的标准是(1)ABC的日期在第二张表中的开始日期和结束日期之间,以及(2)分数匹配。

我想过尝试对每个表进行排序,然后按照索引字段的方式工作。我可以在每个表上创建一个索引字段,然后如果第一个表中的第一条记录匹配第二条记录中的第三条记录,那么我知道所有未来的匹配都会有index_2> 3。这会阻止任何人被重用。

虽然我不能把它放在一起。

感谢您的帮助!我喜欢学习SQL并欣赏新技巧!

+1

ddl和样本采样数据会使这更容易。 sqlfiddle.com是一个很好的开始。 – 2014-09-25 17:46:30

回答

0

djm50,

我不能这样做,在一个SQL语句,这应该给你你在找什么。

'#MatchedRows'包含与选择标准匹配的两个表的所有字段。在光标内部,我跟踪已经使用过的成员,这是我第一次将行#添加到'#SelectedRows'表中。我在MatchedRows和SelectedRows上做了一个内连接,以获得你想要的结果。

DECLARE @row_number INT 
    ,@member1 VARCHAR(1) 
    ,@member2 VARCHAR(1); 

IF OBJECT_ID('tempdb..#UsedMember') IS NOT NULL 
    DROP TABLE #UsedMember; 

IF OBJECT_ID('tempdb..#SelectedRows') IS NOT NULL 
    DROP TABLE #SelectedRows; 

IF OBJECT_ID('tempdb..#MatchedRows') IS NOT NULL 
    DROP TABLE #MatchedRows; 

Create Table #UsedMember (Member varchar(1)); 
Create Table #SelectedRows (rowId int); 

SELECT ROW_NUMBER() OVER (
     ORDER BY T1.MEMBER 
     ) AS Row 
    ,T1.Member T1_Member 
    ,T1.DATE T1_Date 
    ,T1.Score T1_Score 
    ,T2.[Member] [T2_Member] 
    ,T2.[StartDate] [T2_StartDate] 
    ,T2.[EndDate] [T2_EndDate] 
    ,T2.[Score] [T2_Score] 
INTO #MatchedRows 
FROM TableABC T1 
    ,TableDEFG T2 
WHERE (
     T1.DATE BETWEEN T2.StartDate 
      AND T2.EndDate 
     ) 
    AND T1.Score = T2.Score 


-- select * from #MatchedRows 

DECLARE member_cursor CURSOR 
FOR 
SELECT T1.Row AS Row 
    ,T1.T1_Member AS Member1 
    ,T1.T2_Member AS Member2 
FROM #MatchedRows T1 

OPEN member_cursor 

FETCH NEXT 
FROM member_cursor 
INTO @row_number 
    ,@member1 
    ,@member2 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    PRINT '-'; 

    IF NOT EXISTS (
      SELECT 'x' 
      FROM #UsedMember 
      WHERE #UsedMember.Member = @member1 
       OR #UsedMember.Member = @member2 
      ) 
    BEGIN 
     INSERT INTO #UsedMember (Member) 
     VALUES (@member1); 

     INSERT INTO #UsedMember (Member) 
     VALUES (@member2); 

     INSERT INTO #SelectedRows (rowId) 
     VALUES (@row_number); 
    END 

    FETCH NEXT 
    FROM member_cursor 
    INTO @row_number 
     ,@member1 
     ,@member2 
END 

CLOSE member_cursor; 

DEALLOCATE member_cursor; 

SELECT * 
FROM #MatchedRows 
INNER JOIN #SelectedRows ON (#MatchedRows.Row = #SelectedRows.rowId) 
+0

太棒了!谢谢。我认为它可能不得不使用游标,但我不擅长SQL来做徒手画。我对编码有足够的了解,一旦有了轮廓,我就可以适应,所以这应该是完美的。 – djm50 2014-09-25 20:57:47

相关问题