从具有多个比较的表中获取单个结果

时间:2013-10-08 14:07:29

标签: sql

早上好;

我有下表

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 = T2.Date
  5. T1.RID = T2.RID
  6. 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行符合这个标准。但是,我真的只想从表中获得一行。有没有办法做到这一点,或者可能以不同的方式去做呢?

    编辑:添加了其他行 - 不应选择任何行。即使在6/28上存在不匹配的行,它们也会匹配 - 第1行和第3行,第2行和第4行匹配6/28,因此应该限制在最终数据集中。换句话说,如果RID的某一天有任何匹配记录,则不要选择它们。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:0)

两点:

  1. 您必须使用任意条件来过滤双打
  2. 您应该将分组和加入的概念分开
  3. 尝试以下解决方案:

        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