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.持续时间 <> T2.持续时间
  4. T1.Date = T2.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 在一天中有任何匹配的记录,则不要选择它们。

4

3 回答 3

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)
    ;

请参阅此处获取小提琴

于 2013-10-08T15:08:47.397 回答
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
于 2013-10-08T14:27:14.960 回答
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

这是结果!

UDPATE

根据您的新标准,您正在寻找 SO19249978 是您的表名的地方。生成表的子查询Remove选择您不想要的行,然后我们join将它们放到结果中。连接值为空的行是我们正在寻找的,就好像连接匹配我们需要删除这些行一样。

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
于 2013-10-08T14:12:24.037 回答