2013-10-08 121 views
1

早上好,从多个比较表中获取单个结果

我有以下表

Date  Duration   COT    TD   RID 
6/26  30    PT    OT   1 
6/26  15    OT    PT   1 
6/27  60    PT    OT   1 
6/27  60    OT    PT   1 
6/28  15    SS    MM   1 
6/28  30    SS    MM   1 
6/28  15    MM    SS   1 
6/28  30    MM    SS   1 

我所试图做的是通过对自身加入表,其中以下条件为真拉一条记录:

  1. T1.TD = T2。 COT
  2. T1.COT = T2.TD
  3. T1.Duration <> T2.Duration
  4. T1.Date = T 2.Date
  5. T1.RID = T2.RID

T1和T2是相同的表。我到目前为止是:

SELECT * 
FROM T1 
WHERE NOT EXISTS (SELECT 1 FROM T2 
    WHERE T1.Date = T2.Date 
    AND T1.COT = T2.TD 
    AND T1.TD = T2.COT 
    AND T1.RID = T2.RID 
    AND T1.Duration = T2.Duration) 

很明显,上面得到我2行,因为2行符合该条件。但是,我真的只想从表格中获得一行。有没有办法做到这一点,或者有不同的方式去实现它?

编辑:增加了额外的行 - 不应该被选中。尽管6/28行有不匹配的行,但它们确实匹配 - 第1行和第3行,第2行和第4行匹配6/28,因此应该从最终数据集中限制。换句话说,如果RID在一天中有任何匹配记录,则不要选择它们。

+0

正如你所说,你确实会根据你的标准得到两行。如果你想得到一个单行你想获得两个哪一个,并基于哪些额外的标准? – melc

+0

任何一行都可以,因为两者都包含我需要的信息。因此,无论哪个更容易拉动 – user2271146

+0

为什么你说没有你的新行应该被选中? 6/28行符合你提到的所有标准。还有没有规定的另一个规则? – Harrison

回答

0

你快到了。只需使用AS关键字将表格别名为两个不同的名称,然后使用您在问题中提出的标准,如下所示。

Select * from Table as T1 
Join Table as T2 on T1.TD = T2.COT 
AND T1.COT= T2.TD 
AND T1.Duration <> T2.Duration 
AND T1.Date = T2.Date 
AND T1.RID = T2.RID 
WHERE T1.Duration < T2.Duration 

Here are the results!

UDPATE

基于你正在寻找这其中SO19249978是你的表名新的标准。生成Remove表的子查询会选择不需要的行,然后我们将join转换为结果。连接值为null的行是我们正在查找的行,就像连接匹配我们需要删除行一样。

Select T1.Date, T1.Duration as minDur, T2.Duration as maxDur, T1.COT, T1.TD, T1.RID 
from SO19249978 as T1 
Join SO19249978 as T2 on T1.TD = T2.COT 
AND T1.COT= T2.TD 
AND T1.Duration <> T2.Duration 
AND T1.Date = T2.Date 
AND T1.RID = T2.RID 
LEFT JOIN (
    Select Date, Duration, RID 
    from SO19249978 
    GROUP BY Date, Duration, RID 
    Having Count(*) > 1 
    ) as Remove ON T1.Duration=Remove.Duration 
      AND T1.Date= Remove.Date 
      AND t1.RID = Remove.RID 
WHERE Remove.Date is null 
+0

我加了几行。但是,如果第1行和第2行的持续时间不匹配,那么上面的两行都不行。 – user2271146

+0

你是对的,对不起。我修正了它在持续时间不相等的情况下利用您的标准。您可以使用where语句将一行代表一行并删除重复 – Harrison

+0

上述工作很好,直到您添加更多行。我编辑原稿以展开数据集。在上述查询中将选择6/28上的行。我没有在帖子中指定足够的(我的不好),但在6月28日,即使4行有不匹配的行,他们也有匹配的行,所以不应该被选中。 (如果有意义的话) – user2271146

0

您可能需要在最终输出中设置您喜欢哪一行的条件。下面是一些例子:

如果您需要在最终输出的任何随机行:

Select top 1 * from t1 as T1 
Join t1 as T2 on T1.TD = T2.COT 
AND T1.COT= T2.TD 
AND T1.Duration <> T2.Duration 
AND T1.Date1 = T2.Date1 
AND T1.RID = T2.RID  

如果选择基于时间获得行:

Select * from t1 as T1 
Join t1 as T2 on T1.TD = T2.COT 
AND T1.COT= T2.TD 
AND T1.Duration <> T2.Duration 
AND T1.Date1 = T2.Date1 
AND T1.RID 2.RID 
AND T1.duration > T2.duration 
0

两点:

  1. 您必须使用任意条件来过滤双打
  2. 你应该分开分组和加盟

请尝试以下解决方案的概念:

SELECT 
     T1.TD, T1.COT, T1.DATE, T1.RID, MIN(T1.DURATION), MAX(T1.DURATION) 
    FROM 
     DEMO T1 JOIN DEMO T2 ON (
     T1.TD = T2.COT AND 
     T1.COT = T2.TD AND 
     T1.TD < T2.TD -- Arbitrary filtering one of each double 
     ) 
    GROUP BY 
     T1.TD, T1.COT, T1.DATE, T1.RID 
    HAVING 
     MIN(T1.DURATION) <> MAX(T1.DURATION) 
    ; 

在这里看到一个fiddle