返回存在公共ID的行和另一个字段在同一个表

时间:2015-08-27 21:00:21

标签: sql oracle

我想找到SAME ID#有多种文档类型的位置,其中有一个“最终”而不是一个Pitch文档(没有最终版本可以有一个Pitch,但反之亦然)。

ID      Customer       Document Type    Create Date

1001    Acme Sales      Final           01-May-2015 
1001    Acme Sales      Pitch           01-Apr-2015 
1025    XYZ Utility     Final           01-Jan-2015 
1145    ABC Solutions   Pitch           01-Feb-2015

因此,在此示例中,唯一应返回的行是XYZ Utility。

这是我写的,但没有返回任何文件。

SELECT ID, Customer, Document_Type, Create_Date
FROM Files 
WHERE Document_Type = 'Final' AND Document_Type != 'Pitch' 
AND
TO_DATE(Create_Date) BETWEEN '01-JAN-2015' AND '30-JUN-2015'

我尝试了很多其他变种无济于事。

非常感谢任何指导!

3 个答案:

答案 0 :(得分:0)

select f.id, f.Customer, f.Document_Type, f.Create_Date
from (
SELECT ID
FROM Files 
WHERE Document_Type = 'Final' 
AND TO_DATE(Create_Date) BETWEEN '01-JAN-2015' AND '30-JUN-2015'
minus
SELECT ID
FROM Files 
WHERE Document_Type <> 'Final' 
AND TO_DATE(Create_Date) BETWEEN '01-JAN-2015' AND '30-JUN-2015') t
inner join Files f on f.id = t.id

您可以使用minus运算符执行此操作。内部查询会为您提供仅final作为document_type的所有ID。然后,您可以加入原始表格以选择其他列。

答案 1 :(得分:0)

尝试NOT EXISTS:

SELECT ID, Customer, Document_Type, Create_Date
FROM Files f
WHERE Document_Type = 'Final' 
  AND TO_DATE(Create_Date) BETWEEN '01-JAN-2015' AND '30-JUN-2015'
  AND NOT EXISTS
   ( 
     SELECT * FROM Files f2
     WHERE TO_DATE(f2.Create_Date) BETWEEN '01-JAN-2015' AND '30-JUN-2015'
       AND F.id = f2.id  -- same id, but no 'pitch'
       AND f2.Document_Type = 'Pitch' 
   )

答案 2 :(得分:0)

典型的方法是分组:

select ID
from T
group by ID
having
        count(case when DocumentType = 'Final' then 1 else null end) > 0
    and count(case when DocumentType = 'Pitch' then 1 else null end) = 0

有些人更喜欢在这里使用sum(),但我认为count()是表达正在发生的事情的更好方式。另一种可能有用的变化是:

select ID
from T
group by ID
having max(DocumentType) = 'Final' and min(DocumentType) = 'Final'

您没有告诉我们任何其他文档类型,并且在将新类型引入系统时此类查询可能会中断。