0

I've turned this question into a two part question.

I'm trying to understand the logic of self joins but for some reason I get twice as many rows as I think I should be getting here and I don't know why.

I also need to revise my query to prevent the extra row from appearing in the result

The table has user input errors where the begin date of a new ID2 should be the day following the EndDate of the old ID2.

The table is :

ID | BeginDate  | EndDate   | ID2
1  | 2000-01-01 |           | TEN
1  | 2000-01-01 |2010-01-01 | ONEHUNDRED
2  | 2000-01-01 |2011-11-11 | TWENTY
2  | 2011-11-12 |           | TWOHUNDRED
3  | 2000-01-01 |           | THIRTY

I need to do a self join that would expose rows where the BeginDate should have been updated but hasn't been. So for above we would only see the rows for ID1.

I also have a query that should take the one correct ID2 for each ID. The table error will return two ID2's where ID = 1 when I only want the correct one; the query is below.

SELECT ID2 
FROM TABLE1
WHERE inDate BETWEEN BeginDate AND NVL(EndDate, SYSDATE);

I had tried something like this SELECT ID2 FROM TABLE1 WHERE inDate BETWEEN BeginDate AND NVL(MAX(EndDate), SYSDATE);

but MAX obviously won't work in the where clause.

All my self joins to try and expose these errors such as the one below return a row for each side.

SELECT v.* 
FROM Table1 v INNER JOIN Table1 v2
ON v.ID = v2.ID
AND v.BeginDate = v2.BeginDate
AND v.ID2 != v2.ID2

I think I just miss the point of how a self join should work.

I don't think I can compare the end date where they are null as Oracle won't do a comparison with Nulls.

Does anyone have any insight as to what I would need to compare in Table1 in a self join to only show the rows from one side of a self join?

Thanks

4

3 回答 3

1

id和上没有唯一键begin_date,因此您可能希望distinct输出为

SELECT DISTINCT v.*
  FROM Table1 v INNER JOIN Table1 v2
    ON v.ID = v2.ID
   AND v.BeginDate = v2.BeginDate
   AND v.ID2 != v2.ID2;

或者

SELECT DISTINCT v.*
  FROM Table1 v , Table1 v2
 WHERE v.ID = v2.ID
   AND v.BeginDate = v2.BeginDate
   AND v.ID2 != v2.ID2;
于 2012-08-15T22:52:04.407 回答
1

要获得预期的行数,请更改v.ID2 != v2.ID2v.ID2 < v2.ID2

于 2012-08-15T22:14:53.493 回答
0

这种自我加入将为您提供 numrows*numrows 记录。但是你用进一步的规则来限制它。与 null 比较将始终返回 false,但它会起作用。

总共应该是 numrows*numrows-numrows-nulls。

于 2012-08-15T22:12:41.670 回答