使用嵌套的语句或子查询来过滤此结果集

时间:2012-09-08 15:37:17

标签: sql oracle oracle11g

这个问题是Changing this query to group rows and filter out all rows apart from the one with smallest value的延续,但最后还有一点......

我有以下结果集:

275     72.87368055555555555555555555555555555556   foo    70
275     72.87390046296296296296296296296296296296   foo    90 
113     77.06431712962962962962962962962962962963   foo    80
113     77.07185185185185185185185185185185185185   foo    60 

我从这个查询中得到了:

SELECT id, (tbl2.date_modified - tbl1.date_submitted)/86400, some_value
FROM tbl1, tbl2, tbl3
WHERE tbl1.id = tbl2.fid 
AND tbl1.id = tbl3.fid

请注意,有4行有2个ID。我想过滤行以获得第二列中的最小数字。这修好了它:

SELECT id, min((tbl2.date_modified - tbl1.date_submitted)/86400), max(some_value)
FROM tbl1, tbl2, tbl3
WHERE tbl1.id = tbl2.fid 
AND tbl1.id = tbl3.fid
GROUP BY tbl1.id

所以我得到了:

275     72.87368055555555555555555555555555555556   foo    70
113     77.06431712962962962962962962962962962963   foo    80

如何更改它以执行相同但不包括其他行some_value=90的行?即。

113     77.06431712962962962962962962962962962963   foo    80

我想我需要一些嵌套组或嵌套查询?!

非常感谢:)。

3 个答案:

答案 0 :(得分:1)

您应该可以使用NOT EXISTS

SELECT id, 
  min((tbl2.date_modified - tbl1.date_submitted)/86400), 
  max(some_value)
FROM tbl1, tbl2, tbl3
WHERE tbl1.id = tbl2.fid 
  AND tbl1.id = tbl3.fid
  AND NOT EXISTS (SELECT id 
                  FROM tbl2 
                  WHERE tbl1.id = tbl2.fid
                    AND some_value = 90)
GROUP BY tbl1.id

或使用ANSI连接语法:

SELECT id, 
  min((tbl2.date_modified - tbl1.date_submitted)/86400), 
  max(some_value)
FROM tbl1
INNER JOIN tbl2
   ON tbl1.id = tbl2.fid 
INNER JOIN tbl3
   ON tbl1.id = tbl3.fid
WHERE NOT EXISTS (SELECT id 
                  FROM tbl2 
                  WHERE tbl1.id = tbl2.fid
                    AND some_value = 90)
GROUP BY tbl1.id

答案 1 :(得分:1)

您可以使用where not exists

select a.id, min((b.date_modified - a.date_submitted)/86400), max(some_value)
  from tbl1 a
  join tbl2 b
    on a.id = b.fid 
  join tbl3 c
    on a.id = c.fid
 where not exists ( select 1 
                      from tbl2
                     where fid = a.id 
                       and some_value >= 90 )
 group by a.id

not in

select a.id, min((b.date_modified - a.date_submitted)/86400), max(some_value)
  from tbl1 a
  join tbl2 b
    on a.id = b.fid 
  join tbl3 c
    on a.id = c.fid
 where a.id not in ( select fid 
                       from tbl2 
                        and some_value >= 90 )
 group by a.id

答案 2 :(得分:1)

首先,您应该使用标准JOIN语法编写查询。如果您只想排除some_value = 90的行,请在WHERE子句中执行此操作:

SELECT id, min((tbl2.date_modified - tbl1.date_submitted)/86400), max(some_value)
FROM tbl1 join
     tbl2
     on tbl1.id = tbl2.fid join
     tbl3
     on tbl1.id = tbl3.fid
WHERE somevalue = 90
GROUP BY tbl1.id

我不确定你的意思是“不包括其他行,其中some_value = 90”。如果你的意思是排除所有结果行,如果有90,那么使用HAVING子句:

SELECT id, min((tbl2.date_modified - tbl1.date_submitted)/86400), max(some_value)
FROM tbl1 join
     tbl2
     on tbl1.id = tbl2.fid join
     tbl3
     on tbl1.id = tbl3.fid
GROUP BY tbl1.id
HAVING sum(case when somevalue = 90 then 1 else 0 end) > 0

另一个提示:总是包含列的别名,因此每个人都知道它们来自哪个表。